ZQuest Classic Coverage Report


Directory: src/
File: src/zc/maps.cpp
Date: 2025-08-18 06:27:36
Exec Total Coverage
Lines: 4070 5069 80.3%
Functions: 290 328 88.4%
Branches: 3120 5097 61.2%

Line Branch Exec Source
1 #include "base/combo.h"
2 #include "base/handles.h"
3 #include "base/util.h"
4 #include "base/zdefs.h"
5 #include "base/general.h"
6 #include <cstring>
7 #include <assert.h>
8 #include <math.h>
9 #include <vector>
10 #include <deque>
11 #include <string>
12 #include <set>
13 #include <array>
14 #include <sstream>
15 using std::set;
16
17 #include "base/qrs.h"
18 #include "base/dmap.h"
19 #include "base/mapscr.h"
20 #include "base/misctypes.h"
21 #include "base/initdata.h"
22 #include "zc/maps.h"
23 #include "zc/zelda.h"
24 #include "zc/zc_ffc.h"
25 #include "tiles.h"
26 #include "sprite.h"
27 #include "gui/jwin.h"
28 #include "base/zsys.h"
29 #include "subscr.h"
30 #include "zc/zc_subscr.h"
31 #include "zc/hero.h"
32 #include "zc/guys.h"
33 #include "zc/ffscript.h"
34 #include "drawing.h"
35 #include "zc/combos.h"
36 #include "zc/replay.h"
37 #include "slopes.h"
38 #include "particles.h"
39 #include <fmt/format.h>
40 #include "zc/render.h"
41 #include "iter.h"
42 #include <ranges>
43
44 // All the temporary screens (and their layers) for the currently loaded map.
45 static mapscr* temporary_screens[136*7];
46 // Set by load_region.
47 static bool screen_in_current_region[136];
48 412 static rpos_handle_t current_region_rpos_handles[136*7];
49 static bool current_region_rpos_handles_dirty;
50 static int current_region_screen_count;
51 static std::pair<const rpos_handle_t*, int> current_region_rpos_handles_scr[136];
52
53 viewport_t viewport;
54 static int viewport_sprite_uid;
55 ViewportMode viewport_mode;
56 int world_w, world_h;
57 int region_scr_dx, region_scr_dy;
58 int region_scr_count;
59 rpos_t region_max_rpos;
60 int region_num_rpos;
61 region_t cur_region, scrolling_region;
62
63 412 maze_state_t maze_state;
64 int scrolling_maze_last_solved_screen;
65
66 575 void maps_init_game_vars()
67 {
68 575 viewport = {};
69 575 viewport_mode = ViewportMode::CenterAndBound;
70 575 viewport_sprite_uid = 1;
71 575 currscr_for_passive_subscr = -1;
72 575 }
73
74 static region_ids_t current_region_ids;
75
76 14616166 static bool is_a_region(int map, int scr)
77 {
78 14616166 return get_region_id(map, scr) != 0;
79 }
80
81 2232 static bool is_same_region_id(int region_origin_scr, int map, int scr)
82 {
83
2/2
✓ Branch 0 taken 772 times.
✓ Branch 1 taken 1460 times.
2232 if (!is_a_region(map, scr)) return false;
84 1460 int region_id = get_region_id(map, region_origin_scr);
85
1/2
✓ Branch 0 taken 1460 times.
✗ Branch 1 not taken.
1460 return region_id && region_id == get_region_id(map, scr);
86 2232 }
87
88 137749126 bool is_in_current_region(int map, int screen)
89 {
90
5/6
✓ Branch 0 taken 137747553 times.
✓ Branch 1 taken 1573 times.
✓ Branch 2 taken 137747553 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 12213 times.
✓ Branch 5 taken 137735340 times.
137749126 return map == cur_map && screen >= 0 && screen < 128 && screen_in_current_region[screen];
91 }
92
93 69622303 bool is_in_current_region(int screen)
94 {
95
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 69622302 times.
69622303 return screen < 128 && screen_in_current_region[screen];
96 }
97
98 28995045 bool is_in_current_region(mapscr* scr)
99 {
100
4/4
✓ Branch 0 taken 28980024 times.
✓ Branch 1 taken 15021 times.
✓ Branch 2 taken 462663 times.
✓ Branch 3 taken 28517361 times.
28995045 return scr->map == cur_map && scr->screen < 128 && screen_in_current_region[scr->screen];
101 }
102
103 bool is_in_scrolling_region(int screen)
104 {
105 if (!screenscrolling) return false;
106
107 int x = screen % 16;
108 int y = screen / 16;
109 return
110 scrolling_region.origin_screen_x >= x && scrolling_region.origin_screen_x < x + scrolling_region.screen_width &&
111 scrolling_region.origin_screen_y >= y && scrolling_region.origin_screen_y < y + scrolling_region.screen_height;
112 }
113
114 9016036605 bool is_in_scrolling_region()
115 {
116 9016036605 return cur_region.screen_count > 1;
117 }
118
119 76829448 bool is_extended_height_mode()
120 {
121
2/2
✓ Branch 0 taken 76579314 times.
✓ Branch 1 taken 250134 times.
76829448 return cur_region.screen_height > 1 && (DMaps[cur_dmap].flags & dmfEXTENDEDVIEWPORT);
122 }
123
124 // Returns 0 if this is not a region.
125 15658208 int get_region_id(int map, int screen)
126 {
127
2/2
✓ Branch 0 taken 401435 times.
✓ Branch 1 taken 15256773 times.
15658208 if (screen >= 128) return 0;
128
2/2
✓ Branch 0 taken 15255673 times.
✓ Branch 1 taken 1100 times.
15256773 if (map == cur_region.map) return current_region_ids[screen];
129
130 1100 return Regions[map].get_region_id(screen);
131 15658208 }
132
133 982758 int get_current_region_id()
134 {
135 982758 return get_region_id(cur_map, cur_screen);
136 }
137
138 64215 void calculate_region(int map, int screen, region_t& region, int& region_scr_dx, int& region_scr_dy)
139 {
140 64215 region.map = map;
141
142
3/4
✓ Branch 0 taken 274 times.
✓ Branch 1 taken 63941 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 274 times.
64215 if (!(is_a_region(map, screen)) || screen >= 0x80)
143 {
144 63941 region.region_id = 0;
145 63941 region.origin_screen = screen;
146 63941 region.origin_screen_x = screen % 16;
147 63941 region.origin_screen_y = screen / 16;
148 63941 region.screen_width = 1;
149 63941 region.screen_height = 1;
150 63941 region.screen_count = 1;
151 63941 region.width = 256;
152 63941 region.height = 176;
153 63941 region_scr_dx = 0;
154 63941 region_scr_dy = 0;
155 63941 return;
156 }
157
158 274 int input_scr_x = screen % 16;
159 274 int input_scr_y = screen / 16;
160
161 // For the given screen, find the top-left corner of its region.
162 274 int origin_scr_x = input_scr_x;
163 274 int origin_scr_y = input_scr_y;
164 274 int origin_scr = screen;
165
2/2
✓ Branch 0 taken 62 times.
✓ Branch 1 taken 372 times.
434 while (origin_scr_x > 0)
166 {
167
2/2
✓ Branch 0 taken 212 times.
✓ Branch 1 taken 160 times.
372 if (!is_same_region_id(origin_scr, map, map_scr_xy_to_index(origin_scr_x - 1, origin_scr_y))) break;
168 160 origin_scr_x--;
169 }
170
2/2
✓ Branch 0 taken 94 times.
✓ Branch 1 taken 414 times.
508 while (origin_scr_y > 0)
171 {
172
2/2
✓ Branch 0 taken 180 times.
✓ Branch 1 taken 234 times.
414 if (!is_same_region_id(origin_scr, map, map_scr_xy_to_index(origin_scr_x, origin_scr_y - 1))) break;
173 234 origin_scr_y--;
174 }
175 274 origin_scr = map_scr_xy_to_index(origin_scr_x, origin_scr_y);
176
177 // Now find the bottom-right corner.
178 274 int region_scr_right = origin_scr_x;
179
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 614 times.
642 while (region_scr_right < 15)
180 {
181
2/2
✓ Branch 0 taken 246 times.
✓ Branch 1 taken 368 times.
614 if (!is_same_region_id(origin_scr, map, map_scr_xy_to_index(region_scr_right + 1, origin_scr_y))) break;
182 368 region_scr_right++;
183 }
184 274 int region_scr_bottom = origin_scr_y;
185
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 832 times.
856 while (region_scr_bottom < 7)
186 {
187
2/2
✓ Branch 0 taken 250 times.
✓ Branch 1 taken 582 times.
832 if (!is_same_region_id(origin_scr, map, map_scr_xy_to_index(origin_scr_x, region_scr_bottom + 1))) break;
188 582 region_scr_bottom++;
189 }
190
191 274 region.region_id = get_region_id(map, origin_scr);
192 274 region.origin_screen = origin_scr;
193 274 region.origin_screen_x = origin_scr_x;
194 274 region.origin_screen_y = origin_scr_y;
195 274 region.screen_width = region_scr_right - origin_scr_x + 1;
196 274 region.screen_height = region_scr_bottom - origin_scr_y + 1;
197 274 region.screen_count = region.screen_width * region.screen_height;
198 274 region.width = 256 * region.screen_width;
199 274 region.height = 176 * region.screen_height;
200 274 region_scr_dx = input_scr_x - origin_scr_x;
201 274 region_scr_dy = input_scr_y - origin_scr_y;
202
203 DCHECK_RANGE_INCLUSIVE(region.screen_width, 0, 16);
204 DCHECK_RANGE_INCLUSIVE(region.screen_height, 0, 8);
205 64215 }
206
207 35854 void load_region(int dmap, int screen)
208 {
209 35854 clear_temporary_screens();
210
211 35854 int map = DMaps[dmap].map;
212 35854 current_region_ids = Regions[map].get_all_region_ids();
213
214 35854 calculate_region(map, screen, cur_region, region_scr_dx, region_scr_dy);
215 35854 cur_screen = cur_region.origin_screen;
216 35854 world_w = cur_region.width;
217 35854 world_h = cur_region.height;
218 35854 region_scr_count = cur_region.screen_count;
219 35854 region_max_rpos = (rpos_t)(cur_region.screen_count*176 - 1);
220 35854 region_num_rpos = cur_region.screen_count*176;
221 35854 scrolling_maze_last_solved_screen = 0;
222
223 35854 memset(screen_in_current_region, false, sizeof(screen_in_current_region));
224
2/2
✓ Branch 0 taken 36088 times.
✓ Branch 1 taken 35854 times.
71942 for (int x = 0; x < cur_region.screen_width; x++)
225 {
226
2/2
✓ Branch 0 taken 37098 times.
✓ Branch 1 taken 36088 times.
73186 for (int y = 0; y < cur_region.screen_height; y++)
227 {
228 37098 int screen = cur_screen + x + y*16;
229
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 37098 times.
37098 if (screen < 136)
230 {
231 37098 screen_in_current_region[screen] = true;
232 37098 }
233 37098 }
234 36088 }
235
236 35854 mark_current_region_handles_dirty();
237 35854 }
238
239 35854 static void prepare_current_region_handles()
240 {
241 35854 current_region_rpos_handles_dirty = false;
242 35854 current_region_screen_count = 0;
243
2/2
✓ Branch 0 taken 36202 times.
✓ Branch 1 taken 35854 times.
72056 for (int y = 0; y < cur_region.screen_height; y++)
244 {
245
2/2
✓ Branch 0 taken 37098 times.
✓ Branch 1 taken 36202 times.
73300 for (int x = 0; x < cur_region.screen_width; x++)
246 {
247 37098 int screen = cur_screen + x + y*16;
248 37098 int index_start = current_region_screen_count;
249
2/2
✓ Branch 0 taken 37098 times.
✓ Branch 1 taken 259686 times.
296784 for (int layer = 0; layer <= 6; layer++)
250 {
251 259686 mapscr* scr = get_scr_layer(screen, layer);
252
2/2
✓ Branch 0 taken 84550 times.
✓ Branch 1 taken 175136 times.
259686 if (!scr->is_valid())
253 {
254
1/2
✓ Branch 0 taken 175136 times.
✗ Branch 1 not taken.
175136 if (layer == 0) break;
255 175136 continue;
256 }
257
258 84550 rpos_t base_rpos = POS_TO_RPOS(0, get_region_relative_dx(screen), get_region_relative_dy(screen));
259 84550 current_region_rpos_handles[current_region_screen_count] = {scr, screen, layer, base_rpos, 0};
260 84550 current_region_screen_count += 1;
261 84550 }
262
263 37098 int num_handles_for_scr = current_region_screen_count - index_start;
264 37098 current_region_rpos_handles_scr[screen] = {&current_region_rpos_handles[index_start], num_handles_for_scr};
265 37098 }
266 36202 }
267 35854 }
268
269 1782359281 std::tuple<const rpos_handle_t*, int> get_current_region_handles()
270 {
271 DCHECK(!current_region_rpos_handles_dirty);
272 1782359281 return {current_region_rpos_handles, current_region_screen_count};
273 }
274
275 11056526 std::tuple<const rpos_handle_t*, int> get_current_region_handles(mapscr* scr)
276 {
277 DCHECK(!current_region_rpos_handles_dirty);
278
2/4
✓ Branch 0 taken 11056526 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 11056526 times.
11056526 if (scr == special_warp_return_scr || current_region_rpos_handles_dirty)
279 return {nullptr, 0};
280
281
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11056526 times.
11056526 if (cur_screen >= 0x80)
282 {
283 DCHECK(scr == origin_scr);
284 return {nullptr, 0};
285 }
286
287 DCHECK(is_in_current_region(scr));
288 11056526 return current_region_rpos_handles_scr[scr->screen];
289 11056526 }
290
291 35854 void mark_current_region_handles_dirty()
292 {
293 35854 current_region_rpos_handles_dirty = true;
294 35854 }
295
296 64941 void delete_temporary_screens(mapscr** screens)
297 {
298
2/2
✓ Branch 0 taken 61823832 times.
✓ Branch 1 taken 64941 times.
61888773 for (int i = 0; i < 136*7; i++)
299 {
300
2/2
✓ Branch 0 taken 255689 times.
✓ Branch 1 taken 61568143 times.
61823832 if (!screens[i])
301 61568143 continue;
302
303 255689 mapscr* scr = screens[i];
304 255689 int num_ffcs = scr->numFFC();
305
2/2
✓ Branch 0 taken 7619480 times.
✓ Branch 1 taken 255689 times.
7875169 for (int i = 0; i < num_ffcs; i++)
306 {
307 7619480 sprite* ffc = &scr->ffcs[i];
308
2/2
✓ Branch 0 taken 7617623 times.
✓ Branch 1 taken 1857 times.
7619480 if (ffc->uid)
309 1857 FFCore.release_sprite_owned_objects(ffc->uid);
310 7619480 }
311
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 255689 times.
255689 delete scr;
312 255689 screens[i] = NULL;
313 255689 }
314 64941 }
315
316 36991 void clear_temporary_screens()
317 {
318 36991 delete_temporary_screens(temporary_screens);
319 36991 origin_scr = nullptr;
320 36991 hero_scr = nullptr;
321 36991 }
322
323 27954 std::vector<mapscr*> take_temporary_scrs()
324 {
325
1/2
✓ Branch 0 taken 27954 times.
✗ Branch 1 not taken.
27954 std::vector<mapscr*> screens(temporary_screens, temporary_screens + 136*7);
326
2/2
✓ Branch 0 taken 27954 times.
✓ Branch 1 taken 26612208 times.
26640162 for (int i = 0; i < 136*7; i++)
327 26612208 temporary_screens[i] = nullptr;
328
329 27954 return screens;
330
1/2
✓ Branch 0 taken 27954 times.
✗ Branch 1 not taken.
27954 }
331
332 14550079 void calculate_viewport(viewport_t& viewport, int dmap, int screen, int world_w, int world_h, int x, int y)
333 {
334 // TODO: In future, maybe add x/y centering offsets to zscript (Viewport->TargetXOffset/Viewport->TargetYOffset).
335
336
2/2
✓ Branch 0 taken 14503497 times.
✓ Branch 1 taken 46582 times.
14550079 bool extended_height_mode = (DMaps[dmap].flags & dmfEXTENDEDVIEWPORT) && world_h > 176;
337 14550079 viewport.w = 256;
338 14550079 viewport.h = 176 + (extended_height_mode ? 56 : 0);
339
340
2/2
✓ Branch 0 taken 360 times.
✓ Branch 1 taken 14549719 times.
14550079 if (viewport_mode == ViewportMode::Script)
341 360 return;
342
343
2/2
✓ Branch 0 taken 46162 times.
✓ Branch 1 taken 14503557 times.
14549719 if (!is_a_region(DMaps[dmap].map, screen))
344 {
345 14503557 viewport.x = 0;
346 14503557 viewport.y = 0;
347 14503557 }
348
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 46162 times.
46162 else if (viewport_mode == ViewportMode::CenterAndBound)
349 {
350 // Clamp the viewport to the edges of the region.
351
6/6
✓ Branch 0 taken 8568 times.
✓ Branch 1 taken 37594 times.
✓ Branch 2 taken 6788 times.
✓ Branch 3 taken 39374 times.
✓ Branch 4 taken 8568 times.
✓ Branch 5 taken 30806 times.
46162 viewport.x = CLAMP(0, world_w - viewport.w, x - viewport.w/2);
352
6/6
✓ Branch 0 taken 11856 times.
✓ Branch 1 taken 34306 times.
✓ Branch 2 taken 5650 times.
✓ Branch 3 taken 40512 times.
✓ Branch 4 taken 11856 times.
✓ Branch 5 taken 28656 times.
46162 viewport.y = CLAMP(0, world_h - viewport.h, y - viewport.h/2);
353 46162 }
354 else if (viewport_mode == ViewportMode::Center)
355 {
356 viewport.x = x - viewport.w/2;
357 viewport.y = y - viewport.h/2;
358 }
359 14550079 }
360
361 14549568 sprite* get_viewport_sprite()
362 {
363 14549568 sprite* spr = sprite::getByUID(viewport_sprite_uid);
364
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 14549562 times.
14549568 if (!spr)
365 {
366 6 viewport_sprite_uid = 1; // Hero uid.
367 6 spr = &Hero;
368 6 }
369
370 14549568 return spr;
371 }
372
373 6 void set_viewport_sprite(sprite* spr)
374 {
375 6 viewport_sprite_uid = spr->uid;
376 6 }
377
378 14521614 void update_viewport()
379 {
380 14521614 sprite* spr = get_viewport_sprite();
381 14521614 int x = spr->x + spr->txsz*16/2;
382 14521614 int y = spr->y + spr->tysz*16/2;
383 14521614 calculate_viewport(viewport, cur_dmap, cur_screen, world_w, world_h, x, y);
384 14521614 }
385
386 14309416 void update_heroscr()
387 {
388 void playLevelMusic();
389
390 14309416 int x = vbound(Hero.getX().getInt(), 0, world_w - 1);
391 14309416 int y = vbound(Hero.getY().getInt(), 0, world_h - 1);
392 14309416 int dx = x / 256;
393 14309416 int dy = y / 176;
394 14309416 int new_screen = cur_screen + dx + dy * 16;
395
2/2
✓ Branch 0 taken 14301654 times.
✓ Branch 1 taken 7762 times.
14309416 if (maze_state.active == 1)
396 7762 new_screen = maze_state.scr->screen;
397
7/12
✓ Branch 0 taken 216 times.
✓ Branch 1 taken 14309200 times.
✓ Branch 2 taken 216 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 216 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 216 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 216 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 216 times.
14309416 if (hero_screen != new_screen && dx >= 0 && dy >= 0 && dx < 16 && dy < 8 && is_in_current_region(new_screen))
398 {
399 216 region_scr_dx = dx;
400 216 region_scr_dy = dy;
401 216 hero_screen = new_screen;
402 216 prev_hero_scr = hero_scr;
403 216 hero_scr = get_scr(hero_screen);
404 216 Hero.screen_spawned = hero_screen;
405 216 playLevelMusic();
406 216 }
407
1/2
✓ Branch 0 taken 14309416 times.
✗ Branch 1 not taken.
14309416 if (game->get_regionmapping() == REGION_MAPPING_PHYSICAL)
408 mark_visited(new_screen); // Mark each screen the hero steps foot in as visited
409 14309416 }
410
411 4722 mapscr* determine_hero_screen_from_coords()
412 {
413 4722 int x = vbound(Hero.getX().getInt(), 0, world_w - 1);
414 4722 int y = vbound(Hero.getY().getInt(), 0, world_h - 1);
415 4722 int dx = x / 256;
416 4722 int dy = y / 176;
417 4722 return get_scr(cur_screen + dx + dy * 16);
418 }
419
420 26924 bool edge_of_region(direction dir)
421 {
422
2/2
✓ Branch 0 taken 26844 times.
✓ Branch 1 taken 80 times.
26924 if (!is_in_scrolling_region()) return true;
423
424 80 int screen_x = hero_screen % 16;
425 80 int screen_y = hero_screen / 16;
426
2/2
✓ Branch 0 taken 78 times.
✓ Branch 1 taken 2 times.
80 if (dir == up) screen_y -= 1;
427
2/2
✓ Branch 0 taken 70 times.
✓ Branch 1 taken 10 times.
80 if (dir == down) screen_y += 1;
428
2/2
✓ Branch 0 taken 50 times.
✓ Branch 1 taken 30 times.
80 if (dir == left) screen_x -= 1;
429
2/2
✓ Branch 0 taken 42 times.
✓ Branch 1 taken 38 times.
80 if (dir == right) screen_x += 1;
430
4/8
✓ Branch 0 taken 80 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 80 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 80 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 80 times.
✗ Branch 7 not taken.
80 if (screen_x < 0 || screen_x > 16 || screen_y < 0 || screen_y > 8) return true;
431 80 return !is_in_current_region(map_scr_xy_to_index(screen_x, screen_y));
432 26924 }
433
434 // x, y are world coordinates (aka, in relation to origin screen at the top-left).
435 // Coordinates are clamped to the world bounds.
436 212153779 int get_screen_for_world_xy(int x, int y)
437 {
438
2/2
✓ Branch 0 taken 189364167 times.
✓ Branch 1 taken 22789612 times.
212153779 if (!is_in_scrolling_region())
439 189364167 return cur_screen;
440
441 22789612 int dx = std::clamp(x, 0, world_w - 1) / 256;
442 22789612 int dy = std::clamp(y, 0, world_h - 1) / 176;
443 22789612 int origin_screen_x = cur_screen % 16;
444 22789612 int origin_screen_y = cur_screen / 16;
445 22789612 int scr_x = origin_screen_x + dx;
446 22789612 int scr_y = origin_screen_y + dy;
447 22789612 return map_scr_xy_to_index(scr_x, scr_y);
448 212153779 }
449
450 32518504 int get_screen_for_rpos(rpos_t rpos)
451 {
452 32518504 int origin_screen_x = cur_screen % 16;
453 32518504 int origin_screen_y = cur_screen / 16;
454 32518504 int screen = static_cast<int32_t>(rpos) / 176;
455 32518504 int scr_x = origin_screen_x + screen%cur_region.screen_width;
456 32518504 int scr_y = origin_screen_y + screen/cur_region.screen_width;
457 32518504 return map_scr_xy_to_index(scr_x, scr_y);
458 }
459
460 774411837 rpos_handle_t get_rpos_handle(rpos_t rpos, int layer)
461 {
462 DCHECK_LAYER_ZERO_INDEX(layer);
463
2/2
✓ Branch 0 taken 742031293 times.
✓ Branch 1 taken 32380544 times.
774411837 if (!is_in_scrolling_region())
464 742031293 return {get_scr_layer(cur_screen, layer), cur_screen, layer, rpos, RPOS_TO_POS(rpos)};
465 32380544 int screen = get_screen_for_rpos(rpos);
466 32380544 mapscr* scr = get_scr_layer(screen, layer);
467 32380544 return {scr, screen, layer, rpos, RPOS_TO_POS(rpos)};
468 774411837 }
469
470 // x, y are world coordinates (aka, in relation to origin screen at the top-left).
471 // Coordinates are clamped to the world bounds.
472 3492398730 rpos_handle_t get_rpos_handle_for_world_xy(int x, int y, int layer)
473 {
474 3492398730 x = std::clamp(x, 0, world_w - 1);
475 3492398730 y = std::clamp(y, 0, world_h - 1);
476
477 DCHECK_LAYER_ZERO_INDEX(layer);
478
2/2
✓ Branch 0 taken 3464661558 times.
✓ Branch 1 taken 27737172 times.
3492398730 if (!is_in_scrolling_region())
479 {
480 3464661558 int pos = COMBOPOS(x, y);
481 3464661558 return {get_scr_layer(cur_screen, layer), cur_screen, layer, (rpos_t)pos, pos};
482 }
483 27737172 return get_rpos_handle(COMBOPOS_REGION(x, y), layer);
484 3492398730 }
485
486 // Return a rpos_handle_t for a screen-specific `pos` (0-175).
487 1926 rpos_handle_t get_rpos_handle_for_screen(int screen, int layer, int pos)
488 {
489 DCHECK_LAYER_ZERO_INDEX(layer);
490 1926 return {get_scr_layer(screen, layer), screen, layer, POS_TO_RPOS(pos, screen), pos};
491 }
492
493 // Return a rpos_handle_t for a screen-specific `pos` (0-175).
494 // Use this instead of the other `get_pos_handle_for_screen` if you already have a reference to the screen.
495 62247 rpos_handle_t get_rpos_handle_for_scr(mapscr* scr, int layer, int pos)
496 {
497 DCHECK_LAYER_ZERO_INDEX(layer);
498 62247 return {scr, scr->screen, layer, POS_TO_RPOS(pos, scr->screen), pos};
499 }
500
501 25183265 void change_rpos_handle_layer(rpos_handle_t& rpos_handle, int layer)
502 {
503 DCHECK_LAYER_ZERO_INDEX(layer);
504 25183265 rpos_handle.layer = layer;
505 25183265 rpos_handle.scr = get_scr_layer(rpos_handle.screen, layer);
506 25183265 }
507
508 // x, y are world coordinates (aka, in relation to origin screen at the top-left).
509 // Coordinates are clamped to the world bounds.
510 52808 combined_handle_t get_combined_handle_for_world_xy(int x, int y, int layer)
511 {
512 DCHECK_LAYER_ZERO_INDEX(layer);
513
514 52808 x = std::clamp(x, 0, world_w - 1);
515 52808 y = std::clamp(y, 0, world_h - 1);
516
517 52808 auto maybe_ffc_handle = getFFCAt(x, y);
518
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 52808 times.
52808 if (maybe_ffc_handle)
519 return maybe_ffc_handle.value();
520
521 52808 auto rpos = COMBOPOS_REGION_B(x, y);
522
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 52808 times.
52808 if (rpos == rpos_t::None)
523 return rpos_handle_t();
524 52808 return get_rpos_handle(rpos, layer);
525 52808 }
526
527 // These functions all return _temporary_ screens. Any modifications made to them (either by the engine
528 // directly or via zscript) only last until the next area is loaded (via loadscr).
529
530 // Returns the screen containing the (x, y) world position.
531 1633890687 mapscr* get_scr_for_world_xy(int x, int y)
532 {
533 // Quick path, but should work the same without.
534
2/2
✓ Branch 0 taken 1622757687 times.
✓ Branch 1 taken 11133000 times.
1633890687 if (!is_in_scrolling_region()) return origin_scr;
535 11133000 return get_scr(get_screen_for_world_xy(x, y));
536 1633890687 }
537
538 24512760 mapscr* get_scr_for_rpos(rpos_t rpos)
539 {
540 // Quick path, but should work the same without.
541
2/2
✓ Branch 0 taken 24374814 times.
✓ Branch 1 taken 137946 times.
24512760 if (!is_in_scrolling_region()) return origin_scr;
542 137946 return get_scr(get_screen_for_rpos(rpos));
543 24512760 }
544
545 14 mapscr* get_scr_for_rpos_layer(rpos_t rpos, int layer)
546 {
547 14 return get_scr_layer(get_screen_for_rpos(rpos), layer);
548 }
549
550 // Note: layer=0 is the base screen, 1 is the first layer, etc.
551 2308652236 mapscr* get_scr_for_world_xy_layer(int x, int y, int layer)
552 {
553 DCHECK_LAYER_ZERO_INDEX(layer);
554
2/2
✓ Branch 0 taken 2297232238 times.
✓ Branch 1 taken 11419998 times.
2308652236 if (!is_in_scrolling_region()) return get_scr_layer(cur_screen, layer);
555
2/2
✓ Branch 0 taken 708934 times.
✓ Branch 1 taken 10711064 times.
11419998 return layer == 0 ?
556 708934 get_scr_for_world_xy(x, y) :
557 10711064 get_scr_layer(get_screen_for_world_xy(x, y), layer);
558 2308652236 }
559
560 1833562811 int get_region_screen_offset(int screen)
561 {
562 1833562811 return get_region_relative_dx(screen) + get_region_relative_dy(screen) * cur_region.screen_width;
563 }
564
565 654676685 int get_screen_for_region_index_offset(int offset)
566 {
567 654676685 int scr_dx = offset % cur_region.screen_width;
568 654676685 int scr_dy = offset / cur_region.screen_width;
569 654676685 int screen = cur_screen + scr_dx + scr_dy*16;
570 654676685 return screen;
571 }
572
573 654492848 mapscr* get_scr_for_region_index_offset(int offset)
574 {
575 654492848 int screen = get_screen_for_region_index_offset(offset);
576 654492848 return get_scr(screen);
577 }
578
579 // The screen at (map, screen) must exist.
580 1421742428 mapscr* get_scr(int map, int screen)
581 {
582 1421742428 mapscr* scr = get_scr_maybe(map, screen);
583
1/2
✓ Branch 0 taken 1421742428 times.
✗ Branch 1 not taken.
1421742428 CHECK(scr);
584 1421742428 return scr;
585 }
586
587 837456727 mapscr* get_scr(int screen)
588 {
589 837456727 return get_scr(cur_map, screen);
590 }
591
592 // Returns null if active screen does not exist.
593 1451287471 mapscr* get_scr_maybe(int map, int screen)
594 {
595 DCHECK_RANGE_INCLUSIVE(screen, 0, 135);
596
597
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1451287471 times.
1451287471 if (map == cur_map)
598 {
599
2/2
✓ Branch 0 taken 1430512535 times.
✓ Branch 1 taken 20774936 times.
1451287471 if (screen == cur_screen)
600 1430512535 return origin_scr;
601
602 20774936 int index = screen*7;
603
2/2
✓ Branch 0 taken 20763846 times.
✓ Branch 1 taken 11090 times.
20774936 if (temporary_screens[index])
604 20763846 return temporary_screens[index];
605
606
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11090 times.
11090 if (screen == home_screen)
607 return special_warp_return_scr;
608 11090 }
609
610
3/6
✓ Branch 0 taken 11090 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11090 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 11090 times.
11090 if (screenscrolling && map == scrolling_map && !FFCore.ScrollingScreensAll.empty())
611 {
612 11090 int index = screen*7;
613
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11090 times.
11090 if (FFCore.ScrollingScreensAll[index])
614 11090 return FFCore.ScrollingScreensAll[index];
615 }
616
617 return nullptr;
618 1451287471 }
619
620 // Note: layer=0 returns the base screen, layer=1 returns the first layer.
621 7053675246 mapscr* get_scr_layer(int map, int screen, int layer)
622 {
623 DCHECK_LAYER_ZERO_INDEX(layer);
624
2/2
✓ Branch 0 taken 6471882271 times.
✓ Branch 1 taken 581792975 times.
7053675246 if (layer == 0)
625 581792975 return get_scr(map, screen);
626
627
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6471882271 times.
6471882271 if (map == cur_map)
628 {
629 6471882271 int index = screen*7 + layer;
630
2/2
✓ Branch 0 taken 6471813871 times.
✓ Branch 1 taken 68400 times.
6471882271 if (temporary_screens[index])
631 6471813871 return temporary_screens[index];
632
633
2/2
✓ Branch 0 taken 1860 times.
✓ Branch 1 taken 66540 times.
68400 if (screen == home_screen)
634 1860 return &special_warp_return_scrs[layer];
635 66540 }
636
637
1/2
✓ Branch 0 taken 66540 times.
✗ Branch 1 not taken.
66540 if (screenscrolling && map == scrolling_map && !FFCore.ScrollingScreensAll.empty())
638 {
639 66540 int index = screen*7 + layer;
640
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 66540 times.
66540 if (FFCore.ScrollingScreensAll[index])
641 66540 return FFCore.ScrollingScreensAll[index];
642 }
643
644 NOTREACHED();
645 7053675246 }
646
647 // Note: layer=0 returns the base screen, layer=1 returns the first layer.
648 6654529130 mapscr* get_scr_layer(int screen, int layer)
649 {
650 6654529130 return get_scr_layer(cur_map, screen, layer);
651 }
652
653 // Note: layer=0 returns the base screen, layer=1 returns the first layer.
654 // Return nullptr if screen is not valid.
655 397072313 mapscr* get_scr_layer_valid(int screen, int layer)
656 {
657
2/2
✓ Branch 0 taken 78265267 times.
✓ Branch 1 taken 318807046 times.
397072313 if (mapscr* scr = get_scr_layer(cur_map, screen, layer); scr->is_valid())
658 78265267 return scr;
659 318807046 return nullptr;
660 397072313 }
661
662 401 mapscr* get_scr_current_region_dir(int screen, direction dir)
663 {
664 401 int x = get_region_relative_dx(screen);
665 401 int y = get_region_relative_dy(screen);
666
3/4
✓ Branch 0 taken 71 times.
✓ Branch 1 taken 330 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 71 times.
401 if (dir == left && x == 0)
667 71 return nullptr;
668
3/4
✓ Branch 0 taken 92 times.
✓ Branch 1 taken 238 times.
✓ Branch 2 taken 92 times.
✗ Branch 3 not taken.
330 if (dir == right && x == 15)
669 return nullptr;
670
3/4
✓ Branch 0 taken 49 times.
✓ Branch 1 taken 281 times.
✓ Branch 2 taken 49 times.
✗ Branch 3 not taken.
330 if (dir == down && y == 7)
671 return nullptr;
672
3/4
✓ Branch 0 taken 189 times.
✓ Branch 1 taken 141 times.
✓ Branch 2 taken 189 times.
✗ Branch 3 not taken.
330 if (dir == up && y == 0)
673 189 return nullptr;
674
675 141 screen = screen_index_direction(screen, dir);
676
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 141 times.
141 if (is_in_current_region(screen))
677 return get_scr(screen);
678
679 141 return nullptr;
680 401 }
681
682 183837 ffc_handle_t get_ffc_handle(ffc_id_t id)
683 {
684 183837 uint8_t screen = get_screen_for_region_index_offset(id / MAXFFCS);
685 183837 uint8_t i = id % MAXFFCS;
686 183837 mapscr* scr = get_scr(screen);
687 183837 ffcdata* ffc = &scr->getFFC(id % MAXFFCS);
688 183837 return {scr, screen, id, i, ffc};
689 }
690
691 34566 std::pair<int32_t, int32_t> translate_screen_coordinates_to_world(int screen, int x, int y)
692 {
693 34566 x += get_region_relative_dx(screen) * 256;
694 34566 y += get_region_relative_dy(screen) * 176;
695 34566 return {x, y};
696 }
697
698 1049500 std::pair<int32_t, int32_t> translate_screen_coordinates_to_world(int screen)
699 {
700 1049500 int x = get_region_relative_dx(screen) * 256;
701 1049500 int y = get_region_relative_dy(screen) * 176;
702 1049500 return {x, y};
703 }
704
705 12130462748 int32_t COMBOPOS(int32_t x, int32_t y)
706 {
707 DCHECK(x >= 0 && x < 256 && y >= 0 && y < 176);
708 12130462748 return (y & 0xF0) + (x >> 4);
709 }
710 int32_t COMBOPOS_B(int32_t x, int32_t y)
711 {
712 if(unsigned(x) >= 256 || unsigned(y) >= 176)
713 return -1;
714 return (y & 0xF0) + (x >> 4);
715 }
716 3334371711 int32_t COMBOX(int32_t pos)
717 {
718 3334371711 return pos % 16 * 16;
719 }
720 3334371711 int32_t COMBOY(int32_t pos)
721 {
722 3334371711 return pos & 0xF0;
723 }
724
725 112622847 rpos_t COMBOPOS_REGION(int32_t x, int32_t y)
726 {
727
2/2
✓ Branch 0 taken 84070201 times.
✓ Branch 1 taken 28552646 times.
112622847 if (!is_in_scrolling_region())
728 84070201 return (rpos_t) COMBOPOS(x, y);
729
730 DCHECK(is_in_world_bounds(x, y));
731 28552646 int scr_dx = x / (16*16);
732 28552646 int scr_dy = y / (11*16);
733 28552646 int pos = COMBOPOS(x%256, y%176);
734 28552646 return static_cast<rpos_t>((scr_dx + scr_dy * cur_region.screen_width)*176 + pos);
735 112622847 }
736 6305089824 rpos_t COMBOPOS_REGION_B(int32_t x, int32_t y)
737 {
738
2/2
✓ Branch 0 taken 1401168 times.
✓ Branch 1 taken 6303688656 times.
6305089824 if (!is_in_world_bounds(x, y))
739 1401168 return rpos_t::None;
740
741 6303688656 int scr_dx = x / (16*16);
742 6303688656 int scr_dy = y / (11*16);
743 6303688656 int pos = COMBOPOS(x%256, y%176);
744 6303688656 return static_cast<rpos_t>((scr_dx + scr_dy * cur_region.screen_width)*176 + pos);
745 6305089824 }
746 25287068 std::pair<int32_t, int32_t> COMBOXY_REGION(rpos_t rpos)
747 {
748 25287068 int scr_index = static_cast<int32_t>(rpos) / 176;
749 25287068 int scr_dx = scr_index % cur_region.screen_width;
750 25287068 int scr_dy = scr_index / cur_region.screen_width;
751 25287068 int pos = RPOS_TO_POS(rpos);
752 25287068 int x = scr_dx*16*16 + COMBOX(pos);
753 25287068 int y = scr_dy*11*16 + COMBOY(pos);
754 25287068 return {x, y};
755 }
756 60396 int32_t COMBOX_REGION(rpos_t rpos)
757 {
758 60396 auto [x, y] = COMBOXY_REGION(rpos);
759 60396 return x;
760 }
761 12225 int32_t COMBOY_REGION(rpos_t rpos)
762 {
763 12225 auto [x, y] = COMBOXY_REGION(rpos);
764 12225 return y;
765 }
766
767 70177 rpos_t COMBOPOS_REGION_INDEX(int32_t x, int32_t y)
768 {
769 DCHECK(is_in_world_bounds(x, y));
770
1/2
✓ Branch 0 taken 70177 times.
✗ Branch 1 not taken.
70177 if (!is_in_scrolling_region())
771 70177 return (rpos_t)(x + y * 16);
772
773 int scr_dx = x / 16;
774 int scr_dy = y / 11;
775 x %= 16;
776 y %= 11;
777 return static_cast<rpos_t>((scr_dx + scr_dy * cur_region.screen_width)*176 + x + y * 16);
778 70177 }
779 70632 std::pair<int32_t, int32_t> COMBOXY_REGION_INDEX(rpos_t rpos)
780 {
781 70632 int scr_index = static_cast<int32_t>(rpos) / 176;
782 70632 int scr_dx = scr_index % cur_region.screen_width;
783 70632 int scr_dy = scr_index / cur_region.screen_width;
784 70632 int pos = RPOS_TO_POS(rpos);
785 70632 int x = scr_dx*16 + pos%16;
786 70632 int y = scr_dy*11 + pos/16;
787 70632 return {x, y};
788 }
789
790 88504176 int32_t mapind(int32_t map, int32_t scr)
791 {
792 88504176 return map * MAPSCRSNORMAL + scr;
793 }
794
795 FONT *get_zc_font(int index);
796
797 extern sprite_list guys, items, Ewpns, Lwpns, chainlinks, decorations;
798 extern movingblock mblock2; //mblock[4]?
799 extern portal mirror_portal;
800
801 void Z_message_d(const char *format,...)
802 {
803 #ifdef _DEBUG
804 char buf[512];
805 va_list ap;
806 va_start(ap, format);
807 vsprintf(buf, format, ap);
808 va_end(ap);
809
810 al_trace("%s",buf);
811 #else
812 format=format;
813 #endif
814 }
815
816
817
818 bool checktrigger=false;
819
820 void debugging_box(int32_t x1, int32_t y1, int32_t x2, int32_t y2)
821 {
822 //reference/optimization: the start of the unused drawing command index can now be queried. -Gleeok
823 int32_t index = script_drawing_commands.GetNext();
824
825 if(index < 0)
826 return;
827
828 int32_t *sdci = &script_drawing_commands[index][0];
829
830 sdci[0] = RECTR;
831 sdci[1] = 30000;
832 sdci[2] = x1*10000;
833 sdci[3] = y1*10000;
834 sdci[4] = x2*10000;
835 sdci[5] = y2*10000;
836 sdci[6] = 10000;
837 sdci[7] = 10000;
838 sdci[8] = 0;
839 sdci[9] = 0;
840 sdci[10] = 0;
841 sdci[11] = 10000;
842 sdci[12] = 1280000;
843 }
844
845 void clear_dmap(word i)
846 {
847 DMaps[i].clear();
848 }
849
850 void clear_dmaps()
851 {
852 for(int32_t i=0; i<MAXDMAPS; i++)
853 {
854 clear_dmap(i);
855 }
856 }
857
858 223615827 int32_t isdungeon(int32_t dmap, int32_t screen)
859 {
860
2/2
✓ Branch 0 taken 223570147 times.
✓ Branch 1 taken 45680 times.
223615827 if (dmap < 0) dmap = cur_dmap;
861
862 // dungeons can have any dlevel above 0
863
2/2
✓ Branch 0 taken 122366382 times.
✓ Branch 1 taken 101249445 times.
223615827 if((DMaps[dmap].type&dmfTYPE) == dmDNGN)
864 {
865
2/2
✓ Branch 0 taken 9961 times.
✓ Branch 1 taken 101239484 times.
101249445 if (get_canonical_scr(cur_map, screen)->flags6&fCAVEROOM)
866 9961 return 0;
867
868 101239484 return 1;
869 }
870
871 // dlevels that aren't dungeons are caves
872
2/2
✓ Branch 0 taken 36827 times.
✓ Branch 1 taken 122329555 times.
122366382 if (get_canonical_scr(cur_map, screen)->flags6&fDUNGEONROOM)
873 36827 return 1;
874
875 122329555 return 0;
876 223615827 }
877
878 39942476 int32_t isdungeon(int32_t screen)
879 {
880 39942476 return isdungeon(cur_dmap, screen);
881 }
882
883 183546414 int32_t isdungeon()
884 {
885 183546414 return isdungeon(cur_dmap, hero_screen);
886 }
887
888 88932 bool canPermSecret(int32_t dmap, int32_t screen)
889 {
890
2/2
✓ Branch 0 taken 13910 times.
✓ Branch 1 taken 75022 times.
88932 return (!isdungeon(dmap, screen) || get_qr(qr_DUNGEON_DMAPS_PERM_SECRETS));
891 }
892
893 1375748203 int32_t MAPCOMBO(int32_t x, int32_t y)
894 {
895 1375748203 x = vbound(x, 0, world_w-1);
896 1375748203 y = vbound(y, 0, world_h-1);
897 1375748203 int pos = COMBOPOS(x%256, y%176);
898 1375748203 mapscr* scr = get_scr_for_world_xy(x, y);
899 1375748203 return scr->data[pos];
900 }
901
902 //specific layers 1 to 6
903 1709728262 int32_t MAPCOMBOL(int32_t layer,int32_t x,int32_t y)
904 {
905 DCHECK(layer >= 1 && layer <= 6);
906
3/4
✓ Branch 0 taken 1689370280 times.
✓ Branch 1 taken 20357982 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1689370280 times.
1709728262 if (!is_in_world_bounds(x, y) || layer <= 0)
907 20357982 return 0;
908
909 1689370280 mapscr* m = get_scr_for_world_xy_layer(x, y, layer);
910
2/2
✓ Branch 0 taken 496888043 times.
✓ Branch 1 taken 1192482237 times.
1689370280 if (!m->is_valid())
911 1192482237 return 0;
912
913 496888043 int pos = COMBOPOS(x%256, y%176);
914 496888043 return m->data[pos];
915 1709728262 }
916
917 int32_t MAPCSETL(int32_t layer,int32_t x,int32_t y)
918 {
919 DCHECK(layer >= 1 && layer <= 6);
920 if (!is_in_world_bounds(x, y) || layer <= 0)
921 return 0;
922
923 mapscr* m = get_scr_for_world_xy_layer(x, y, layer);
924 if (!m->is_valid())
925 return 0;
926
927 int pos = COMBOPOS(x%256, y%176);
928 return m->cset[pos];
929 }
930
931 189308 int32_t MAPFLAGL(int32_t layer,int32_t x,int32_t y)
932 {
933 DCHECK(layer >= 1 && layer <= 6);
934
2/4
✓ Branch 0 taken 189308 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 189308 times.
189308 if (!is_in_world_bounds(x, y) || layer <= 0)
935 return 0;
936
937 189308 mapscr* m = get_scr_for_world_xy_layer(x, y, layer);
938
2/2
✓ Branch 0 taken 148914 times.
✓ Branch 1 taken 40394 times.
189308 if (!m->is_valid())
939 40394 return 0;
940
941 148914 int pos = COMBOPOS(x%256, y%176);
942 148914 return m->sflag[pos];
943 189308 }
944
945 6281 int32_t COMBOTYPEL(int32_t layer,int32_t x,int32_t y)
946 {
947 DCHECK(layer >= 1 && layer <= 6);
948
2/4
✓ Branch 0 taken 6281 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 6281 times.
6281 if (!is_in_world_bounds(x, y) || layer <= 0)
949 return 0;
950
951 6281 mapscr* m = get_scr_for_world_xy_layer(x, y, layer);
952
2/2
✓ Branch 0 taken 5809 times.
✓ Branch 1 taken 472 times.
6281 if (!m->is_valid())
953 472 return 0;
954
955 5809 int pos = COMBOPOS(x%256, y%176);
956 5809 return combobuf[m->data[pos]].type;
957 6281 }
958
959 189308 int32_t MAPCOMBOFLAGL(int32_t layer,int32_t x,int32_t y)
960 {
961 DCHECK(layer >= 1 && layer <= 6);
962
2/4
✓ Branch 0 taken 189308 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 189308 times.
189308 if (!is_in_world_bounds(x, y) || layer <= 0)
963 return 0;
964
965 189308 mapscr* m = get_scr_for_world_xy_layer(x, y, layer);
966
2/2
✓ Branch 0 taken 148914 times.
✓ Branch 1 taken 40394 times.
189308 if (!m->is_valid())
967 40394 return 0;
968
969 148914 int pos = COMBOPOS(x%256, y%176);
970 148914 return combobuf[m->data[pos]].flag;
971 189308 }
972
973
974 // True if the FFC covers x, y and is not ethereal or a changer.
975 2467525204 bool ffcIsAt(const ffc_handle_t& ffc_handle, int32_t x, int32_t y)
976 {
977
2/2
✓ Branch 0 taken 746716438 times.
✓ Branch 1 taken 1720808766 times.
2467525204 if (ffc_handle.data()<=0)
978 746716438 return false;
979
980
2/2
✓ Branch 0 taken 300884500 times.
✓ Branch 1 taken 1419924266 times.
1720808766 if((ffc_handle.ffc->flags&(ffc_changer|ffc_ethereal))!=0)
981 300884500 return false;
982
983 1419924266 int32_t fx=ffc_handle.ffc->x.getInt();
984
4/4
✓ Branch 0 taken 976336635 times.
✓ Branch 1 taken 443587631 times.
✓ Branch 2 taken 866205573 times.
✓ Branch 3 taken 110131062 times.
1419924266 if(x<fx || x>fx+(ffc_handle.scr->ffEffectWidth(ffc_handle.i)-1)) // FFC sizes are weird.
985 1309793204 return false;
986
987 110131062 int32_t fy=ffc_handle.ffc->y.getInt();
988
4/4
✓ Branch 0 taken 80147053 times.
✓ Branch 1 taken 29984009 times.
✓ Branch 2 taken 60079253 times.
✓ Branch 3 taken 20067800 times.
110131062 if(y<fy || y>fy+(ffc_handle.scr->ffEffectHeight(ffc_handle.i)-1))
989 90063262 return false;
990
991 20067800 return true;
992 2467525204 }
993
994 999075493 int32_t MAPFFCOMBO(int32_t x,int32_t y)
995 {
996
2/2
✓ Branch 0 taken 13163663 times.
✓ Branch 1 taken 985911830 times.
999075493 if (auto ffc_handle = getFFCAt(x, y))
997 13163663 return ffc_handle->data();
998 985911830 return 0;
999 999075493 }
1000
1001 207232 int32_t MAPCSET(int32_t x, int32_t y)
1002 {
1003
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 207232 times.
207232 if (!is_in_world_bounds(x, y))
1004 return 0;
1005 207232 mapscr* scr = get_scr_for_world_xy(x, y);
1006 207232 int pos = COMBOPOS(x%256, y%176);
1007 207232 return scr->cset[pos];
1008 207232 }
1009
1010 73664988 int32_t MAPFLAG(int32_t x, int32_t y)
1011 {
1012
2/2
✓ Branch 0 taken 28140 times.
✓ Branch 1 taken 73636848 times.
73664988 if (!is_in_world_bounds(x, y))
1013 28140 return 0;
1014 73636848 mapscr* scr = get_scr_for_world_xy(x, y);
1015 73636848 int pos = COMBOPOS(x%256, y%176);
1016 73636848 return scr->sflag[pos];
1017 73664988 }
1018
1019 163184591 int32_t COMBOTYPE(int32_t x,int32_t y)
1020 {
1021 163184591 int32_t b=1;
1022
2/2
✓ Branch 0 taken 95232965 times.
✓ Branch 1 taken 67951626 times.
163184591 if(x&8) b<<=2;
1023
2/2
✓ Branch 0 taken 81540582 times.
✓ Branch 1 taken 81644009 times.
163184591 if(y&8) b<<=1;
1024
1025
2/2
✓ Branch 0 taken 326362144 times.
✓ Branch 1 taken 163177292 times.
489539436 for (int32_t i = 0; i <= 1; ++i)
1026 {
1027
2/2
✓ Branch 0 taken 316029196 times.
✓ Branch 1 taken 10332948 times.
326362144 if (get_qr(qr_OLD_BRIDGE_COMBOS))
1028 {
1029
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 316029196 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
316029196 if (combobuf[MAPCOMBO2(i,x,y)].type == cBRIDGE && !_walkflag_layer(x, y, i)) return cNONE;
1030 316029196 }
1031 else
1032 {
1033
4/4
✓ Branch 0 taken 10451 times.
✓ Branch 1 taken 10322497 times.
✓ Branch 2 taken 3152 times.
✓ Branch 3 taken 7299 times.
10332948 if (combobuf[MAPCOMBO2(i,x,y)].type == cBRIDGE && _effectflag_layer(x, y, i)) return cNONE;
1034 }
1035 326354845 }
1036
1037 163177292 newcombo const& cmb = combobuf[MAPCOMBO(x,y)];
1038
5/6
✓ Branch 0 taken 3590234 times.
✓ Branch 1 taken 159587058 times.
✓ Branch 2 taken 3030548 times.
✓ Branch 3 taken 559686 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 3030548 times.
163177292 if (cmb.type == cWATER && (cmb.walk&b) && ((cmb.walk>>4)&b))
1039 {
1040
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3030548 times.
3030548 if(cmb.usrflags&cflag4) return cSHALLOWWATER;
1041
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3030548 times.
3030548 if(cmb.usrflags&cflag3) return cNONE;
1042 3030548 }
1043 163177292 return cmb.type;
1044 163184591 }
1045
1046 50225603 int32_t FFCOMBOTYPE(int32_t x,int32_t y)
1047 {
1048 50225603 return combobuf[MAPFFCOMBO(x,y)].type;
1049 }
1050
1051 4954844 int32_t FFORCOMBO(int32_t x, int32_t y)
1052 {
1053
2/2
✓ Branch 0 taken 58516 times.
✓ Branch 1 taken 4896328 times.
4954844 if (auto ffc_handle = getFFCAt(x, y))
1054 58516 return ffc_handle->data();
1055
1056 4896328 return MAPCOMBO(x,y);
1057 4954844 }
1058
1059 int32_t FFORCOMBOTYPE(int32_t x, int32_t y)
1060 {
1061 for (int32_t i = 0; i <= 1; ++i)
1062 {
1063 if (get_qr(qr_OLD_BRIDGE_COMBOS))
1064 {
1065 if (combobuf[MAPCOMBO2(i,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,i)) return cNONE;
1066 }
1067 else
1068 {
1069 if (combobuf[MAPCOMBO2(i,x,y)].type == cBRIDGE && _effectflag_layer(x,y,i)) return cNONE;
1070 }
1071 }
1072 int32_t b=1;
1073
1074 if(x&8) b<<=2;
1075
1076 if(y&8) b<<=1;
1077 newcombo const& cmb = combobuf[FFORCOMBO(x,y)];
1078 if (cmb.type == cWATER && (cmb.usrflags&cflag4) && (cmb.walk&b)) return cSHALLOWWATER;
1079 if (cmb.type == cWATER && (cmb.usrflags&cflag3) && (cmb.walk&b)) return cNONE;
1080 return cmb.type;
1081 }
1082
1083 int32_t FFORCOMBO_L(int32_t layer, int32_t x, int32_t y)
1084 {
1085 if (auto ffc_handle = getFFCAt(x, y))
1086 return ffc_handle->data();
1087
1088 return layer ? MAPCOMBOL(layer, x, y) : MAPCOMBO(x,y);
1089 }
1090
1091 int32_t FFORCOMBOTYPE_L(int32_t layer, int32_t x, int32_t y)
1092 {
1093 return combobuf[FFORCOMBO_L(layer,x,y)].type;
1094 }
1095
1096 70154870 int32_t MAPCOMBOFLAG(int32_t x,int32_t y)
1097 {
1098
2/2
✓ Branch 0 taken 27852 times.
✓ Branch 1 taken 70127018 times.
70154870 if (!is_in_world_bounds(x, y))
1099 27852 return 0;
1100
1101 70127018 mapscr* scr = get_scr_for_world_xy(x, y);
1102 70127018 int pos = COMBOPOS(x%256, y%176);
1103 70127018 return combobuf[scr->data[pos]].flag;
1104 70154870 }
1105
1106 56841587 int32_t MAPFFCOMBOFLAG(int32_t x,int32_t y)
1107 {
1108
2/2
✓ Branch 0 taken 746177 times.
✓ Branch 1 taken 56095410 times.
56841587 if (auto ffc_handle = getFFCAt(x, y))
1109 746177 return ffc_handle->cflag();
1110
1111 56095410 return 0;
1112 56841587 }
1113
1114 1313056294 std::optional<ffc_handle_t> getFFCAt(int32_t x, int32_t y)
1115 {
1116 2788859658 return find_ffc([&](const ffc_handle_t& ffc_handle) {
1117 1475803364 return ffcIsAt(ffc_handle, x, y);
1118 });
1119 }
1120
1121 3044 int32_t MAPCOMBO(const rpos_handle_t& rpos_handle)
1122 {
1123
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3044 times.
3044 if (!rpos_handle.scr->is_valid()) return 0;
1124 3044 return rpos_handle.data();
1125 3044 }
1126
1127 3161497057 int32_t MAPCOMBO2(int32_t layer, int32_t x, int32_t y)
1128 {
1129 DCHECK_LAYER_NEG1_INDEX(layer);
1130
2/2
✓ Branch 0 taken 22362112 times.
✓ Branch 1 taken 3139134945 times.
3161497057 if (!is_in_world_bounds(x, y)) return 0;
1131
2/2
✓ Branch 0 taken 3067537150 times.
✓ Branch 1 taken 71597795 times.
3139134945 if (layer == -1) return MAPCOMBO(x, y);
1132
1133 3067537150 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, layer + 1);
1134
2/2
✓ Branch 0 taken 2112128249 times.
✓ Branch 1 taken 955408901 times.
3067537150 if (!rpos_handle.scr->is_valid()) return 0;
1135
1136 955408901 return rpos_handle.data();
1137 3161497057 }
1138
1139 17372399 static void _handle_screen_load_trigger(const combined_handle_t& handle)
1140 {
1141 17372399 auto cid = handle.data();
1142 17372399 auto* cmb = &handle.combo();
1143 17372399 bool done = false;
1144 17372399 std::set<int32_t> visited;
1145
2/2
✓ Branch 0 taken 17372399 times.
✓ Branch 1 taken 17372399 times.
34744798 while(!done)
1146 {
1147
2/4
✓ Branch 0 taken 17372399 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 17372399 times.
17372399 if(visited.contains(cid))
1148 {
1149 Z_error("Combo '%d' was part of an infinite trigger loop, breaking out of loop", cid);
1150 break; // prevent infinite loop
1151 }
1152
1/2
✓ Branch 0 taken 17372399 times.
✗ Branch 1 not taken.
17372399 visited.insert(cid);
1153
1154 17372399 done = true; // don't loop again unless something changes
1155
1/2
✓ Branch 0 taken 17372399 times.
✗ Branch 1 not taken.
17964354 trig_each_combo_trigger(handle, [&](combo_trigger const& trig){
1156 591955 return trig.trigger_flags.get(TRIGFLAG_SCREENLOAD);
1157 });
1158
2/4
✓ Branch 0 taken 17372399 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 17372399 times.
17372399 if(handle.data() != cid)
1159 {
1160 cid = handle.data();
1161 cmb = &handle.combo();
1162 done = false; // loop again for the new combo
1163 }
1164 }
1165 17372399 }
1166 51768 static void handle_screen_load_trigger(const screen_handles_t& screen_handles)
1167 {
1168 51768 for_every_combo_in_screen(screen_handles, _handle_screen_load_trigger);
1169 51768 }
1170 34820 void handle_region_load_trigger()
1171 {
1172
2/2
✓ Branch 0 taken 152 times.
✓ Branch 1 taken 34668 times.
34820 if (is_in_scrolling_region())
1173 {
1174
2/2
✓ Branch 0 taken 152 times.
✓ Branch 1 taken 19456 times.
19608 for (int screen = 0; screen < 128; screen++)
1175 {
1176
2/2
✓ Branch 0 taken 18156 times.
✓ Branch 1 taken 1300 times.
19456 if (is_in_current_region(screen))
1177 1300 handle_screen_load_trigger(create_screen_handles_one(get_scr(screen)));
1178 19456 }
1179 152 }
1180 34668 else handle_screen_load_trigger(create_screen_handles_one(get_scr(hero_screen)));
1181 34820 }
1182
1183 15800 static void apply_state_changes_to_screen(mapscr& scr, int32_t map, int32_t screen, int32_t flags, bool secrets_do_replay_comment)
1184 {
1185 15800 auto screen_handles = create_screen_handles_one(&scr);
1186
1187
3/4
✓ Branch 0 taken 539 times.
✓ Branch 1 taken 15261 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 539 times.
15800 if ((flags & mSECRET) && canPermSecret(cur_dmap, screen))
1188 {
1189 539 reveal_hidden_stairs(&scr, screen, false);
1190 539 bool do_layers = false;
1191 539 bool from_active_screen = false;
1192 539 trigger_secrets_for_screen_internal(screen_handles, do_layers, from_active_screen, -3, secrets_do_replay_comment);
1193 539 }
1194
1/2
✓ Branch 0 taken 15800 times.
✗ Branch 1 not taken.
15800 if (flags & mLIGHTBEAM)
1195 {
1196 for_every_rpos_in_screen(screen_handles, [&](const rpos_handle_t& rpos_handle) {
1197 if (rpos_handle.ctype() == cLIGHTTARGET)
1198 {
1199 if (!(rpos_handle.combo().usrflags&cflag1)) //Unlit version
1200 rpos_handle.increment_data();
1201 }
1202 });
1203 }
1204
1205 15800 int lvl = DMaps[cur_dmap].level;
1206 15800 toggle_switches(game->lvlswitches[lvl], true, screen_handles);
1207 15800 toggle_gswitches_load(screen_handles);
1208
1209
2/2
✓ Branch 0 taken 15708 times.
✓ Branch 1 taken 92 times.
15800 if(flags&mLOCKBLOCK) // if special stuff done before
1210 {
1211 92 remove_screenstatecombos2(screen_handles, false, cLOCKBLOCK, cLOCKBLOCK2);
1212 92 }
1213
1214
1/2
✓ Branch 0 taken 15800 times.
✗ Branch 1 not taken.
15800 if(flags&mBOSSLOCKBLOCK) // if special stuff done before
1215 {
1216 remove_screenstatecombos2(screen_handles, false, cBOSSLOCKBLOCK, cBOSSLOCKBLOCK2);
1217 }
1218
1219
1/2
✓ Branch 0 taken 15800 times.
✗ Branch 1 not taken.
15800 if(flags&mCHEST) // if special stuff done before
1220 {
1221 remove_screenstatecombos2(screen_handles, false, cCHEST, cCHEST2);
1222 }
1223
1224
1/2
✓ Branch 0 taken 15800 times.
✗ Branch 1 not taken.
15800 if(flags&mCHEST) // if special stuff done before
1225 {
1226 remove_screenstatecombos2(screen_handles, false, cLOCKEDCHEST, cLOCKEDCHEST2);
1227 }
1228
1229
1/2
✓ Branch 0 taken 15800 times.
✗ Branch 1 not taken.
15800 if(flags&mBOSSCHEST) // if special stuff done before
1230 {
1231 remove_screenstatecombos2(screen_handles, false, cBOSSCHEST, cBOSSCHEST2);
1232 }
1233
1234
1235 15800 int mi = mapind(map, screen);
1236 15800 clear_xdoors_mi(screen_handles, mi);
1237 15800 clear_xstatecombos_mi(screen_handles, mi);
1238
1239 15800 handle_screen_load_trigger(screen_handles);
1240 15800 }
1241
1242 53194 std::optional<mapscr> load_temp_mapscr_and_apply_secrets(int32_t map, int32_t screen, int32_t layer, bool secrets, bool secrets_do_replay_comment)
1243 {
1244
2/4
✓ Branch 0 taken 53194 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 53194 times.
53194 if (map < 0 || screen < 0)
1245 return std::nullopt;
1246
1247 53194 const mapscr* source = get_canonical_scr(map, screen);
1248
2/2
✓ Branch 0 taken 40960 times.
✓ Branch 1 taken 12234 times.
53194 if (!source->is_valid())
1249 12234 return std::nullopt;
1250
1251
2/2
✓ Branch 0 taken 8308 times.
✓ Branch 1 taken 32652 times.
40960 if (layer >= 0)
1252 {
1253
2/2
✓ Branch 0 taken 25160 times.
✓ Branch 1 taken 7492 times.
32652 if (source->layermap[layer] <= 0)
1254 25160 return std::nullopt;
1255
1256 7492 source = get_canonical_scr(source->layermap[layer] - 1, source->layerscreen[layer]);
1257
1/2
✓ Branch 0 taken 7492 times.
✗ Branch 1 not taken.
7492 if (!source->is_valid())
1258 return std::nullopt;
1259 7492 }
1260
1261
1/2
✓ Branch 0 taken 15800 times.
✗ Branch 1 not taken.
15800 int flags = secrets ? game->maps[mapind(map, screen)] : 0;
1262 15800 mapscr scr = *source;
1263
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15800 times.
15800 apply_state_changes_to_screen(scr, map, screen, flags, secrets_do_replay_comment);
1264
1265 15800 return scr;
1266 53194 }
1267
1268 27203 static int32_t MAPCOMBO3_impl(int32_t map, int32_t screen, int32_t layer, int32_t pos, bool secrets)
1269 {
1270
2/4
✓ Branch 0 taken 27203 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 27203 times.
27203 if (map < 0 || screen < 0) return 0;
1271
1272
2/4
✓ Branch 0 taken 27203 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 27203 times.
27203 if(pos>175 || pos < 0)
1273 return 0;
1274
1275 // TODO: consider caching this (invalidate on any modification via scripting, or anything
1276 // `apply_state_changes_to_screen` checks).
1277
4/5
✓ Branch 0 taken 4976 times.
✓ Branch 1 taken 22227 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 4976 times.
✓ Branch 4 taken 22227 times.
32179 if (auto s = load_temp_mapscr_and_apply_secrets(map, screen, layer, secrets))
1278 4976 return s->data[pos];
1279
1280 22227 return 0;
1281 27203 }
1282
1283 // Read from the current temporary screens or, if (map, screen) is not loaded,
1284 // load that screen and apply the relevant secrets before evaluating the combo at that position.
1285 137738112 int32_t MAPCOMBO3(int32_t map, int32_t screen, int32_t layer, int32_t x, int32_t y, bool secrets)
1286 {
1287 DCHECK_LAYER_NEG1_INDEX(layer);
1288 DCHECK(map >= 0 && screen >= 0);
1289
1290
2/2
✓ Branch 0 taken 137710909 times.
✓ Branch 1 taken 27203 times.
137738112 if (is_in_current_region(map, screen)) return MAPCOMBO2(layer, x, y);
1291
1292 // Screen is not in the current region, so we have to load and trigger some secrets.
1293 27203 int pos = COMBOPOS(x, y);
1294 27203 return MAPCOMBO3_impl(map, screen, layer, pos, secrets);
1295 137738112 }
1296
1297 int32_t MAPCOMBO3(int32_t map, int32_t screen, int32_t layer, rpos_t rpos, bool secrets)
1298 {
1299 DCHECK_LAYER_NEG1_INDEX(layer);
1300 DCHECK(map >= 0 && screen >= 0);
1301 DCHECK(is_valid_rpos(rpos));
1302
1303 if (is_in_current_region(map, screen)) return MAPCOMBO(get_rpos_handle(rpos, layer + 1));
1304
1305 // Screen is not currently loaded, so we have to load and trigger some secrets.
1306 return MAPCOMBO3_impl(map, screen, layer, RPOS_TO_POS(rpos), secrets);
1307 }
1308
1309 int32_t MAPCSET2(int32_t layer,int32_t x,int32_t y)
1310 {
1311 DCHECK_LAYER_NEG1_INDEX(layer);
1312 if (!is_in_world_bounds(x, y))
1313 return 0;
1314 if (layer == -1) return MAPCSET(x, y);
1315
1316 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, layer + 1);
1317 if (!rpos_handle.scr->is_valid()) return 0;
1318
1319 return rpos_handle.cset();
1320 }
1321
1322 98920838 int32_t MAPFLAG2(int32_t layer,int32_t x,int32_t y)
1323 {
1324 DCHECK_LAYER_NEG1_INDEX(layer);
1325
3/4
✓ Branch 0 taken 1894252 times.
✓ Branch 1 taken 97026586 times.
✓ Branch 2 taken 1894252 times.
✗ Branch 3 not taken.
98920838 if (!get_qr(qr_BUGGED_LAYERED_FLAGS) && (!is_in_world_bounds(x, y)))
1326 return 0;
1327
2/2
✓ Branch 0 taken 81313609 times.
✓ Branch 1 taken 17607229 times.
98920838 if (layer == -1) return MAPFLAG(x, y);
1328
1329 81313609 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, layer + 1);
1330
2/2
✓ Branch 0 taken 63007039 times.
✓ Branch 1 taken 18306570 times.
81313609 if (!rpos_handle.scr->is_valid()) return 0;
1331
1332 18306570 return rpos_handle.sflag();
1333 98920838 }
1334
1335 int32_t COMBOTYPE2(int32_t layer,int32_t x,int32_t y)
1336 {
1337 if(layer < 1)
1338 {
1339 for (int32_t i = layer+1; i <= 1; ++i)
1340 {
1341 if (get_qr(qr_OLD_BRIDGE_COMBOS))
1342 {
1343 if (combobuf[MAPCOMBO2(i,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,i)) return cNONE;
1344 }
1345 else
1346 {
1347 if (combobuf[MAPCOMBO2(i,x,y)].type == cBRIDGE && _effectflag_layer(x,y,i)) return cNONE;
1348 }
1349 }
1350 }
1351 if(layer==-1) return COMBOTYPE(x,y);
1352
1353 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, layer + 1);
1354 if (!rpos_handle.scr->is_valid()) return 0;
1355
1356 return rpos_handle.ctype();
1357 }
1358
1359 // Returns the flag for the combo at the given position.
1360 // This is also known as an "inherent flag".
1361 97151985 int32_t MAPCOMBOFLAG2(int32_t layer,int32_t x,int32_t y)
1362 {
1363 DCHECK_LAYER_NEG1_INDEX(layer);
1364
2/2
✓ Branch 0 taken 288 times.
✓ Branch 1 taken 97151697 times.
97151985 if (!is_in_world_bounds(x, y))
1365 288 return 0;
1366
2/2
✓ Branch 0 taken 81255084 times.
✓ Branch 1 taken 15896613 times.
97151697 if (layer == -1) return MAPCOMBOFLAG(x, y);
1367
1368 81255084 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, layer + 1);
1369
2/2
✓ Branch 0 taken 63016952 times.
✓ Branch 1 taken 18238132 times.
81255084 if (!rpos_handle.scr->is_valid()) return 0;
1370
1371 18238132 return rpos_handle.cflag();
1372 97151985 }
1373
1374 11626947 bool HASFLAG(int32_t flag, int32_t layer, rpos_t rpos)
1375 {
1376 DCHECK_LAYER_ZERO_INDEX(layer);
1377 11626947 auto rpos_handle = get_rpos_handle(rpos, layer);
1378
2/2
✓ Branch 0 taken 6436552 times.
✓ Branch 1 taken 5190395 times.
11626947 if (!rpos_handle.scr->is_valid()) return false;
1379
2/2
✓ Branch 0 taken 4565 times.
✓ Branch 1 taken 5185830 times.
5190395 if (rpos_handle.sflag() == flag) return true;
1380
2/2
✓ Branch 0 taken 37705 times.
✓ Branch 1 taken 5148125 times.
5185830 if (rpos_handle.cflag() == flag) return true;
1381 5148125 return false;
1382 11626947 }
1383
1384 1697077 bool HASFLAG_ANY(int32_t flag, rpos_t rpos)
1385 {
1386 DCHECK(is_valid_rpos(rpos));
1387
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1697077 times.
1697077 if (rpos > region_max_rpos) return false;
1388
1389
2/2
✓ Branch 0 taken 11626947 times.
✓ Branch 1 taken 1654807 times.
13281754 for(auto q = 0; q < 7; ++q)
1390 {
1391
2/2
✓ Branch 0 taken 42270 times.
✓ Branch 1 taken 11584677 times.
11626947 if(HASFLAG(flag, q, rpos))
1392 42270 return true;
1393 11584677 }
1394 1654807 return false;
1395 1697077 }
1396
1397 const char *screenstate_string[32] =
1398 {
1399 "Door Up", "Door Down", "Door Left", "Door Right", "Item", "Special Item", "Some Enemies Never Return",
1400 "Temporary No Return", "Lock Blocks", "Boss Lock Blocks", "Chests", "Locked Chests",
1401 "Boss Locked Chests", "Secrets", "Visited", "Light Beams",
1402 "All Enemies Don't Return", "<Unused>", "<Unused>", "<Unused>", "<Unused>", "<Unused>", "<Unused>", "<Unused>",
1403 "<Unused>", "<Unused>", "<Unused>", "<Unused>", "<Unused>", "<Unused>", "<Unused>", "<Unused>",
1404 };
1405
1406 34860 void eventlog_mapflags()
1407 {
1408 34860 std::ostringstream oss;
1409
1410 34860 int mi = mapind(cur_map, home_screen);
1411
1/2
✓ Branch 0 taken 34860 times.
✗ Branch 1 not taken.
34860 dword g = game->maps[mi];
1412
1413
2/4
✓ Branch 0 taken 34860 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 34860 times.
✗ Branch 3 not taken.
34860 oss << fmt::format("Screen ({}, {:02X})", cur_map+1, home_screen);
1414
2/2
✓ Branch 0 taken 14514 times.
✓ Branch 1 taken 20346 times.
34860 if(g) // Main States
1415 {
1416 static const int order[] =
1417 {
1418 mSECRET, mITEM, mSPECIALITEM, mLOCKBLOCK, mBOSSLOCKBLOCK,
1419 mCHEST, mLOCKEDCHEST, mBOSSCHEST,
1420 mDOOR_UP, mDOOR_DOWN, mDOOR_LEFT, mDOOR_RIGHT,
1421 mNEVERRET, mTMPNORET, mLIGHTBEAM, mNO_ENEMIES_RETURN
1422 };
1423
1424
1/2
✓ Branch 0 taken 14514 times.
✗ Branch 1 not taken.
14514 oss << " [";
1425 14514 bool comma = false;
1426
2/2
✓ Branch 0 taken 14514 times.
✓ Branch 1 taken 232224 times.
246738 for(int fl : order)
1427 {
1428
2/2
✓ Branch 0 taken 8979 times.
✓ Branch 1 taken 223245 times.
232224 if(!(g&fl))
1429 223245 continue;
1430 8979 byte ind = byte(log2(double(fl)));
1431
2/2
✓ Branch 0 taken 1922 times.
✓ Branch 1 taken 7057 times.
8979 if(comma)
1432
1/2
✓ Branch 0 taken 1922 times.
✗ Branch 1 not taken.
1922 oss << ", ";
1433
1/2
✓ Branch 0 taken 8979 times.
✗ Branch 1 not taken.
8979 oss << screenstate_string[ind];
1434 8979 comma = true;
1435 }
1436
1/2
✓ Branch 0 taken 14514 times.
✗ Branch 1 not taken.
14514 oss << "]";
1437 14514 }
1438
3/4
✓ Branch 0 taken 34860 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 38 times.
✓ Branch 3 taken 34822 times.
34860 if(game->xstates[mi]) // ExStates
1439 {
1440
1/2
✓ Branch 0 taken 38 times.
✗ Branch 1 not taken.
38 oss << " Ex[";
1441 38 bool comma = false;
1442
2/2
✓ Branch 0 taken 38 times.
✓ Branch 1 taken 1216 times.
1254 for(byte fl = 0; fl < 32; ++fl)
1443 {
1444
3/4
✓ Branch 0 taken 1216 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 44 times.
✓ Branch 3 taken 1172 times.
1216 if(game->xstates[mi] & (1<<fl))
1445 {
1446
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 38 times.
44 if(comma)
1447
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 oss << ", ";
1448
1/2
✓ Branch 0 taken 44 times.
✗ Branch 1 not taken.
44 oss << int(fl);
1449 44 comma = true;
1450 44 }
1451 1216 }
1452
1/2
✓ Branch 0 taken 38 times.
✗ Branch 1 not taken.
38 oss << "]";
1453 38 }
1454 { // ExDoors
1455
2/2
✓ Branch 0 taken 34860 times.
✓ Branch 1 taken 139440 times.
174300 for(int q = 0; q < 4; ++q)
1456 {
1457 139440 bool comma = false;
1458
3/4
✓ Branch 0 taken 139440 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 139438 times.
✓ Branch 3 taken 2 times.
139440 if(auto v = game->xdoors[mi][q])
1459 {
1460
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if(comma)
1461 oss << ",";
1462
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 else oss << " ExDoor";
1463
2/4
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
2 oss << "[" << dirstr[q];
1464
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 16 times.
18 for(int fl = 0; fl < 8; ++fl)
1465
2/2
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 3 times.
19 if(v & (1<<fl))
1466
2/4
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
3 oss << " " << int(fl);
1467
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 oss << "]";
1468 2 comma = true;
1469 2 }
1470 139440 }
1471 }
1472
2/4
✓ Branch 0 taken 34860 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 34860 times.
34860 Z_eventlog("%s\n", oss.str().c_str());
1473 34860 }
1474
1475 // set specific flag
1476 5616 void setmapflag(mapscr* scr, uint32_t flag)
1477 {
1478
2/2
✓ Branch 0 taken 5603 times.
✓ Branch 1 taken 13 times.
5616 if (scr->screen >= 0x80) scr = special_warp_return_scr;
1479 5616 int mi = mapind(cur_map, scr->screen);
1480 5616 setmapflag_mi(scr, mi, flag);
1481 5616 }
1482 57 void setmapflag_homescr(uint32_t flag)
1483 {
1484 57 int mi = mapind(cur_map, home_screen);
1485 57 setmapflag_mi(origin_scr, mi, flag);
1486 57 }
1487 2023 void setmapflag_mi(int32_t mi, uint32_t flag)
1488 {
1489 2023 byte cscr = mi&((1<<7)-1);
1490 2023 byte cmap = (mi>>7);
1491 2023 mapscr* scr = origin_scr;
1492
2/2
✓ Branch 0 taken 834 times.
✓ Branch 1 taken 1189 times.
2023 if (is_in_current_region(cmap, cscr))
1493 1189 scr = get_scr(cmap, cscr);
1494
1495 2023 setmapflag_mi(scr, mi, flag);
1496 2023 }
1497
1498 8478 static void log_state_change(int map, int screen, std::string action)
1499 {
1500
6/6
✓ Branch 0 taken 1913 times.
✓ Branch 1 taken 6565 times.
✓ Branch 2 taken 996 times.
✓ Branch 3 taken 917 times.
✓ Branch 4 taken 352 times.
✓ Branch 5 taken 644 times.
8478 if (is_in_current_region(map, screen) || (map == cur_map && screen == home_screen))
1501 6917 Z_eventlog("[Map %d, Screen %02X (current)] %s\n", map + 1, screen, action.c_str());
1502 else
1503 1561 Z_eventlog("[Map %d, Screen %02X] %s\n", map + 1, screen, action.c_str());
1504 8478 }
1505
1506 7696 void setmapflag_mi(mapscr* scr, int32_t mi, uint32_t flag)
1507 {
1508 7696 byte cscr = mi&((1<<7)-1);
1509 7696 byte cmap = (mi>>7);
1510
1511 7696 double temp=log2((double)flag);
1512
1/2
✓ Branch 0 taken 7696 times.
✗ Branch 1 not taken.
7696 const char* state_string = flag>0 ? screenstate_string[(int32_t)temp] : "<Unknown>";
1513 7696 const char* replay_state_string = state_string;
1514
2/2
✓ Branch 0 taken 7176 times.
✓ Branch 1 taken 520 times.
7696 if(temp == 6) replay_state_string = "No Return";
1515
1516
3/4
✓ Branch 0 taken 7696 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1552 times.
✓ Branch 3 taken 6144 times.
7696 if (replay_is_active() && !(game->maps[mi] & flag))
1517
1/2
✓ Branch 0 taken 6144 times.
✗ Branch 1 not taken.
6144 replay_step_comment(fmt::format("map {} scr {} flag {}", cmap, cscr, replay_state_string));
1518 7696 game->maps[mi] |= flag;
1519
1/2
✓ Branch 0 taken 7696 times.
✗ Branch 1 not taken.
7696 log_state_change(cmap, cscr, fmt::format("State set: {}", state_string));
1520
1521
2/2
✓ Branch 0 taken 2507 times.
✓ Branch 1 taken 5189 times.
7696 if((scr->nocarry&flag)!=flag)
1522 {
1523 5189 byte nmap=TheMaps[((cmap)*MAPSCRS)+cscr].nextmap;
1524 5189 byte nscr=TheMaps[((cmap)*MAPSCRS)+cscr].nextscr;
1525
1526 5189 std::vector<int32_t> done;
1527
2/2
✓ Branch 0 taken 5094 times.
✓ Branch 1 taken 95 times.
5189 bool looped = (nmap==cmap+1 && nscr==cscr);
1528
1529
6/6
✓ Branch 0 taken 406 times.
✓ Branch 1 taken 5147 times.
✓ Branch 2 taken 42 times.
✓ Branch 3 taken 364 times.
✓ Branch 4 taken 364 times.
✓ Branch 5 taken 5189 times.
5553 while((nmap!=0) && !looped && !(nscr>=128))
1530 {
1531
3/4
✓ Branch 0 taken 364 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 171 times.
✓ Branch 3 taken 193 times.
364 if(!(game->maps[((nmap-1)<<7)+nscr] & flag))
1532 {
1533
2/4
✓ Branch 0 taken 193 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 193 times.
✗ Branch 3 not taken.
193 log_state_change(nmap, nscr, "State change carried over");
1534
2/4
✓ Branch 0 taken 193 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 193 times.
✗ Branch 3 not taken.
193 if (replay_is_active())
1535
2/4
✓ Branch 0 taken 193 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 193 times.
✗ Branch 3 not taken.
193 replay_step_comment(fmt::format("map {} scr {} flag {} carry", nmap, nscr, replay_state_string));
1536
1/2
✓ Branch 0 taken 193 times.
✗ Branch 1 not taken.
193 game->maps[((nmap-1)<<7)+nscr] |= flag;
1537 193 }
1538
1539 364 cmap=nmap;
1540 364 cscr=nscr;
1541 364 nmap=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextmap;
1542 364 nscr=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextscr;
1543
1544
2/2
✓ Branch 0 taken 889 times.
✓ Branch 1 taken 364 times.
1253 for(auto it = done.begin(); it != done.end(); it++)
1545 {
1546
2/2
✓ Branch 0 taken 847 times.
✓ Branch 1 taken 42 times.
889 if(*it == ((nmap-1)<<7)+nscr)
1547 42 looped = true;
1548 889 }
1549
1550
1/2
✓ Branch 0 taken 364 times.
✗ Branch 1 not taken.
364 done.push_back(((nmap-1)<<7)+nscr);
1551 }
1552 5189 }
1553 7696 }
1554
1555 void unsetmapflag_home(uint32_t flag, bool anyflag)
1556 {
1557 int mi = mapind(cur_map, home_screen);
1558 unsetmapflag_mi(origin_scr, mi, flag, anyflag);
1559 }
1560
1561 void unsetmapflag(mapscr* scr, uint32_t flag, bool anyflag)
1562 {
1563 if (scr->screen >= 0x80) scr = special_warp_return_scr;
1564 int mi = mapind(cur_map, scr->screen);
1565 unsetmapflag_mi(scr, mi, flag, anyflag);
1566 }
1567
1568 471 void unsetmapflag_mi(int32_t mi, uint32_t flag, bool anyflag)
1569 {
1570 471 byte cscr = mi&((1<<7)-1);
1571 471 byte cmap = (mi>>7);
1572 471 mapscr* scr = origin_scr;
1573
2/2
✓ Branch 0 taken 460 times.
✓ Branch 1 taken 11 times.
471 if (is_in_current_region(cmap, cscr))
1574 11 scr = get_scr(cmap, cscr);
1575
1576 471 unsetmapflag_mi(scr, mi, flag, anyflag);
1577 471 }
1578
1579 471 void unsetmapflag_mi(mapscr* scr, int32_t mi, uint32_t flag, bool anyflag)
1580 {
1581 471 byte cscr = mi&((1<<7)-1);
1582 471 byte cmap = (mi>>7);
1583
1584
2/2
✓ Branch 0 taken 460 times.
✓ Branch 1 taken 11 times.
471 if(anyflag)
1585 460 game->maps[mi] &= ~flag;
1586
2/4
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 11 times.
11 else if(flag==mITEM || flag==mSPECIALITEM)
1587 {
1588 if(!(scr->flags4&fNOITEMRESET))
1589 game->maps[mi] &= ~flag;
1590 }
1591 11 else game->maps[mi] &= ~flag;
1592
1593 471 double temp=log2((double)flag);
1594
1/2
✓ Branch 0 taken 471 times.
✗ Branch 1 not taken.
471 const char* state_string = flag>0 ? screenstate_string[(int32_t)temp] : "<Unknown>";
1595
1/2
✓ Branch 0 taken 471 times.
✗ Branch 1 not taken.
471 log_state_change(cmap, cscr, fmt::format("State unset: {}", state_string));
1596
1597
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 471 times.
471 if((scr->nocarry&flag)!=flag)
1598 {
1599 471 byte nmap=TheMaps[((cmap)*MAPSCRS)+cscr].nextmap;
1600 471 byte nscr=TheMaps[((cmap)*MAPSCRS)+cscr].nextscr;
1601
1602 471 std::vector<int32_t> done;
1603
2/2
✓ Branch 0 taken 466 times.
✓ Branch 1 taken 5 times.
471 bool looped = (nmap==cmap+1 && nscr==cscr);
1604
1605
6/6
✓ Branch 0 taken 90 times.
✓ Branch 1 taken 465 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 84 times.
✓ Branch 4 taken 84 times.
✓ Branch 5 taken 471 times.
555 while((nmap!=0) && !looped && !(nscr>=128))
1606 {
1607
3/4
✓ Branch 0 taken 84 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✓ Branch 3 taken 72 times.
84 if(game->maps[((nmap-1)<<7)+nscr] & flag)
1608 {
1609
2/4
✓ Branch 0 taken 72 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 72 times.
✗ Branch 3 not taken.
72 log_state_change(nmap, nscr, "State change carried over");
1610
1/2
✓ Branch 0 taken 72 times.
✗ Branch 1 not taken.
72 game->maps[((nmap-1)<<7)+nscr] &= ~flag;
1611 72 }
1612
1613 84 cmap=nmap;
1614 84 cscr=nscr;
1615 84 nmap=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextmap;
1616 84 nscr=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextscr;
1617
1618
2/2
✓ Branch 0 taken 84 times.
✓ Branch 1 taken 546 times.
630 for(std::vector<int32_t>::iterator it = done.begin(); it != done.end(); it++)
1619 {
1620
2/2
✓ Branch 0 taken 540 times.
✓ Branch 1 taken 6 times.
546 if(*it == ((nmap-1)<<7)+nscr)
1621 6 looped = true;
1622 546 }
1623
1624
1/2
✓ Branch 0 taken 84 times.
✗ Branch 1 not taken.
84 done.push_back(((nmap-1)<<7)+nscr);
1625 }
1626 471 }
1627 471 }
1628
1629 50173955 bool getmapflag(int32_t screen, uint32_t flag)
1630 {
1631
2/2
✓ Branch 0 taken 1345925 times.
✓ Branch 1 taken 48828030 times.
50173955 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
1632 50173955 return (game->maps[mi] & flag) != 0;
1633 }
1634 6228660 bool getmapflag(mapscr* scr, uint32_t flag)
1635 {
1636 6228660 return getmapflag(scr->screen, flag);
1637 }
1638
1639 60 void setxmapflag(int32_t screen, uint32_t flag)
1640 {
1641
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 60 times.
60 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
1642 60 setxmapflag_mi(mi, flag);
1643 60 }
1644 62 void setxmapflag_mi(int32_t mi, uint32_t flag)
1645 {
1646
2/2
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 41 times.
62 if(game->xstates[mi] & flag) return;
1647 41 byte cscr = mi&((1<<7)-1);
1648 41 byte cmap = (mi>>7);
1649
1650 41 byte temp=(byte)log2((double)flag);
1651
1/2
✓ Branch 0 taken 41 times.
✗ Branch 1 not taken.
41 log_state_change(cmap, cscr, fmt::format("ExtraState set: {}", temp));
1652
1653 41 game->xstates[mi] |= flag;
1654
1655 41 mapscr* scr = origin_scr;
1656
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 41 times.
41 if (is_in_current_region(cmap, cscr))
1657 41 scr = get_scr(cmap, cscr);
1658
1659
1/2
✓ Branch 0 taken 41 times.
✗ Branch 1 not taken.
41 if((scr->exstate_carry&flag)==flag)
1660 {
1661 byte nmap=TheMaps[((cmap)*MAPSCRS)+cscr].nextmap;
1662 byte nscr=TheMaps[((cmap)*MAPSCRS)+cscr].nextscr;
1663
1664 std::vector<int32_t> done;
1665 bool looped = (nmap==cmap+1 && nscr==cscr);
1666
1667 while((nmap!=0) && !looped && !(nscr>=128))
1668 {
1669 if(!(game->maps[((nmap-1)<<7)+nscr] & flag))
1670 {
1671 log_state_change(nmap, nscr, "ExState change carried over");
1672 if (replay_is_active())
1673 replay_step_comment(fmt::format("map {} scr {} exstate {} carry", nmap, nscr, temp));
1674 game->xstates[((nmap-1)<<7)+nscr] |= flag;
1675 }
1676
1677 cmap=nmap;
1678 cscr=nscr;
1679 nmap=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextmap;
1680 nscr=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextscr;
1681
1682 for(auto it = done.begin(); it != done.end(); it++)
1683 {
1684 if(*it == ((nmap-1)<<7)+nscr)
1685 looped = true;
1686 }
1687
1688 done.push_back(((nmap-1)<<7)+nscr);
1689 }
1690 }
1691 62 }
1692 2 void unsetxmapflag(int32_t screen, uint32_t flag)
1693 {
1694
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
1695 2 unsetxmapflag_mi(mi, flag);
1696 2 }
1697 2 void unsetxmapflag_mi(int32_t mi, uint32_t flag)
1698 {
1699
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 if(!(game->xstates[mi] & flag)) return;
1700 1 byte cscr = mi&((1<<7)-1);
1701 1 byte cmap = (mi>>7);
1702 1 byte temp=(byte)log2((double)flag);
1703
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 log_state_change(cmap, cscr, fmt::format("ExtraState unset: {}", temp));
1704 1 game->xstates[mi] &= ~flag;
1705
1706 1 mapscr* scr = origin_scr;
1707
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (is_in_current_region(cmap, cscr))
1708 1 scr = get_scr(cmap, cscr);
1709
1710
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if((scr->exstate_carry&flag)==flag)
1711 {
1712 byte nmap=TheMaps[((cmap)*MAPSCRS)+cscr].nextmap;
1713 byte nscr=TheMaps[((cmap)*MAPSCRS)+cscr].nextscr;
1714
1715 std::vector<int32_t> done;
1716 bool looped = (nmap==cmap+1 && nscr==cscr);
1717
1718 while((nmap!=0) && !looped && !(nscr>=128))
1719 {
1720 if(game->maps[((nmap-1)<<7)+nscr] & flag)
1721 {
1722 log_state_change(nmap, nscr, "ExState change carried over");
1723 game->xstates[((nmap-1)<<7)+nscr] &= ~flag;
1724 }
1725
1726 cmap=nmap;
1727 cscr=nscr;
1728 nmap=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextmap;
1729 nscr=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextscr;
1730
1731 for(std::vector<int32_t>::iterator it = done.begin(); it != done.end(); it++)
1732 {
1733 if(*it == ((nmap-1)<<7)+nscr)
1734 looped = true;
1735 }
1736
1737 done.push_back(((nmap-1)<<7)+nscr);
1738 }
1739 }
1740 2 }
1741 34 bool getxmapflag(int32_t screen, uint32_t flag)
1742 {
1743
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 34 times.
34 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
1744 34 return getxmapflag_mi(mi, flag);
1745 }
1746 471496240 bool getxmapflag_mi(int32_t mi, uint32_t flag)
1747 {
1748 471496240 return (game->xstates[mi] & flag) != 0;
1749 }
1750
1751 4 void setxdoor_mi(uint mi, uint dir, uint ind, bool state)
1752 {
1753
3/6
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 4 times.
4 if(mi > game->xdoors.size() || dir > 3 || ind > 8)
1754 return;
1755
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if(!(game->xdoors[mi][dir] & (1<<ind)) == !state)
1756 return;
1757
1758
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 SETFLAG(game->xdoors[mi][dir], 1<<ind, state);
1759
1760 4 int cscr = mi % MAPSCRSNORMAL;
1761 4 int cmap = mi / MAPSCRSNORMAL;
1762
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if (state)
1763
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 log_state_change(cmap, cscr, fmt::format("ExDoor[{}][{}] set", dirstr[dir], ind));
1764 else
1765 log_state_change(cmap, cscr, fmt::format("ExDoor[{}][{}] unset", dirstr[dir], ind));
1766 4 }
1767 471496201 bool getxdoor_mi(uint mi, uint dir, uint ind)
1768 {
1769
3/6
✓ Branch 0 taken 471496201 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 471496201 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 471496201 times.
471496201 if(mi >= game->xdoors.size() || dir >= 4 || ind >= 8)
1770 return false;
1771 471496201 return (game->xdoors[mi][dir] & (1<<ind));
1772 471496201 }
1773 9 bool getxdoor(int32_t screen, uint dir, uint ind)
1774 {
1775 9 int mi = mapind(cur_map, screen);
1776 9 return getxdoor_mi(mi,dir,ind);
1777 }
1778
1779 401 void set_doorstate_mi(uint mi, uint dir)
1780 {
1781
1/2
✓ Branch 0 taken 401 times.
✗ Branch 1 not taken.
401 if(dir >= 4)
1782 return;
1783 401 setmapflag_mi(mi, mDOOR_UP << dir);
1784
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 400 times.
401 if(auto di = nextscr_mi(mi, dir))
1785 400 setmapflag_mi(*di, mDOOR_UP << oppositeDir[dir]);
1786 401 }
1787 401 void set_doorstate(uint screen, uint dir)
1788 {
1789 401 int mi = mapind(cur_map, screen);
1790 401 set_doorstate_mi(mi, dir);
1791 401 }
1792
1793 2 void set_xdoorstate_mi(uint mi, uint dir, uint ind, bool state)
1794 {
1795
3/6
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
2 if(mi >= game->xdoors.size() || dir >= 4 || ind >= 8)
1796 return;
1797 2 setxdoor_mi(mi, dir, ind, state);
1798
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if(auto di = nextscr_mi(mi, dir))
1799 2 setxdoor_mi(*di, oppositeDir[dir], ind, state);
1800 2 }
1801
1802 2 void set_xdoorstate(int32_t screen,uint dir, uint ind, bool state)
1803 {
1804 2 int mi = mapind(cur_map, screen);
1805 2 set_xdoorstate_mi(mi, dir, ind, state);
1806 2 }
1807
1808 57 int32_t WARPCODE(int32_t dmap,int32_t screen,int32_t dw)
1809 // returns: -1 = not a warp screen
1810 // 0+ = warp screen code ( high byte=dmap, low byte=scr )
1811 {
1812 57 const mapscr *scr = get_canonical_scr(DMaps[dmap].map, screen);
1813
1814
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 57 times.
57 if(scr->room!=rWARP)
1815 return -1;
1816
1817 57 int32_t ring=scr->catchall;
1818 57 int32_t size=QMisc.warp[ring].size;
1819
1820
1/2
✓ Branch 0 taken 57 times.
✗ Branch 1 not taken.
57 if(size==0)
1821 return -2;
1822
1823 57 int32_t index=-1;
1824
1825
2/2
✓ Branch 0 taken 289 times.
✓ Branch 1 taken 57 times.
346 for(int32_t i=0; i<size; i++)
1826
6/6
✓ Branch 0 taken 230 times.
✓ Branch 1 taken 59 times.
✓ Branch 2 taken 173 times.
✓ Branch 3 taken 57 times.
✓ Branch 4 taken 173 times.
✓ Branch 5 taken 57 times.
289 if(dmap==QMisc.warp[ring].dmap[i] && screen==
1827 346 (QMisc.warp[ring].scr[i] + DMaps[dmap].xoff))
1828 57 index=i;
1829
1830
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 57 times.
57 if(index==-1)
1831 return -3;
1832
1833 57 index = (index+dw)%size;
1834 57 return (QMisc.warp[ring].dmap[index] << 8) + QMisc.warp[ring].scr[index];
1835 57 }
1836
1837 14779694 void update_combo_cycling()
1838 {
1839 14779694 auto& combo_cache = combo_caches::can_cycle;
1840
1841 static int32_t newdata[176];
1842 static int32_t newcset[176];
1843 static bool initialized=false;
1844
1845 // Just a simple bit of optimization
1846
2/2
✓ Branch 0 taken 14779383 times.
✓ Branch 1 taken 311 times.
14779694 if(!initialized)
1847 {
1848
2/2
✓ Branch 0 taken 54736 times.
✓ Branch 1 taken 311 times.
55047 for(int32_t i=0; i<176; i++)
1849 {
1850 54736 newdata[i]=-1;
1851 54736 newcset[i]=-1;
1852 54736 }
1853
1854 311 initialized=true;
1855 311 }
1856
1857 14779694 std::set<uint16_t> restartanim;
1858
1859
1/2
✓ Branch 0 taken 14779694 times.
✗ Branch 1 not taken.
29948756 for_every_base_screen_in_region([&](mapscr* scr, unsigned int region_scr_x, unsigned int region_scr_y) {
1860 15169062 int screen = scr->screen;
1861 int32_t x;
1862
1863
2/2
✓ Branch 0 taken 2669754912 times.
✓ Branch 1 taken 15169062 times.
2684923974 for(int32_t i=0; i<176; i++)
1864 {
1865 2669754912 x=scr->data[i];
1866 2669754912 auto& mini_cmb = combo_cache.minis[x];
1867
2/2
✓ Branch 0 taken 3273932 times.
✓ Branch 1 taken 2666480980 times.
2669754912 if (!mini_cmb.can_cycle)
1868 2666480980 continue;
1869
1870 3273932 newcombo const& cmb = combobuf[x];
1871
1872 //time to restart
1873
4/4
✓ Branch 0 taken 902694 times.
✓ Branch 1 taken 2371238 times.
✓ Branch 2 taken 474434 times.
✓ Branch 3 taken 428260 times.
3273932 if ((cmb.aclk>=cmb.speed) && combocheck(cmb))
1874 {
1875 428260 bool cycle_under = (cmb.animflags & AF_CYCLEUNDERCOMBO);
1876
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 428260 times.
428260 auto c = cycle_under ? scr->undercombo : cmb.nextcombo;
1877 428260 newdata[i] = c;
1878
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 428240 times.
428260 if(!(cmb.animflags & AF_CYCLENOCSET))
1879
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 428240 times.
428240 newcset[i] = cycle_under ? scr->undercset : cmb.nextcset;
1880
1881
2/2
✓ Branch 0 taken 427216 times.
✓ Branch 1 taken 1044 times.
428260 if(combobuf[c].animflags & AF_CYCLE)
1882 {
1883 1044 restartanim.insert(c);
1884 1044 }
1885 428260 }
1886 3273932 }
1887
1888 15169062 int rpos_base = (int)POS_TO_RPOS(0, region_scr_x, region_scr_y);
1889
2/2
✓ Branch 0 taken 2669754912 times.
✓ Branch 1 taken 15169062 times.
2684923974 for(int32_t i=0; i<176; i++)
1890 {
1891
2/2
✓ Branch 0 taken 428260 times.
✓ Branch 1 taken 2669326652 times.
2669754912 if(newdata[i]==-1)
1892 2669326652 continue;
1893
1894 428260 rpos_t rpos = (rpos_t)(rpos_base + i);
1895 428260 rpos_handle_t rpos_handle = {scr, screen, 0, rpos, i};
1896 428260 screen_combo_modify_preroutine(rpos_handle);
1897 428260 scr->data[i]=newdata[i];
1898
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 428240 times.
428260 if(newcset[i]>-1)
1899 428240 scr->cset[i]=newcset[i];
1900 428260 screen_combo_modify_postroutine(rpos_handle);
1901
1902 428260 newdata[i]=-1;
1903 428260 newcset[i]=-1;
1904 428260 }
1905
1906 15169062 word c = scr->numFFC();
1907
2/2
✓ Branch 0 taken 15169062 times.
✓ Branch 1 taken 453640163 times.
468809225 for(word i=0; i<c; i++)
1908 {
1909 453640163 ffcdata& ffc = scr->ffcs[i];
1910 453640163 auto& mini_cmb = combo_cache.minis[ffc.data];
1911
2/2
✓ Branch 0 taken 4173 times.
✓ Branch 1 taken 453635990 times.
453640163 if (!mini_cmb.can_cycle)
1912 453635990 continue;
1913
1914 4173 newcombo const& cmb = combobuf[ffc.data];
1915
1916 //time to restart
1917
4/4
✓ Branch 0 taken 611 times.
✓ Branch 1 taken 3562 times.
✓ Branch 2 taken 503 times.
✓ Branch 3 taken 108 times.
4173 if ((cmb.aclk>=cmb.speed) && combocheck(cmb))
1918 {
1919 108 bool cycle_under = (cmb.animflags & AF_CYCLEUNDERCOMBO);
1920
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 108 times.
108 auto c = cycle_under ? scr->undercombo : cmb.nextcombo;
1921 108 zc_ffc_set(ffc, c);
1922
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 108 times.
108 if(!(cmb.animflags & AF_CYCLENOCSET))
1923
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 108 times.
108 ffc.cset = cycle_under ? scr->undercset : cmb.nextcset;
1924
1925
2/2
✓ Branch 0 taken 48 times.
✓ Branch 1 taken 60 times.
108 if(combobuf[ffc.data].animflags & AF_CYCLE)
1926 {
1927 60 restartanim.insert(ffc.data);
1928 60 }
1929 108 }
1930 4173 }
1931
1932
2/2
✓ Branch 0 taken 8418399 times.
✓ Branch 1 taken 6750663 times.
15169062 if(get_qr(qr_CMBCYCLELAYERS))
1933 {
1934
2/2
✓ Branch 0 taken 40503978 times.
✓ Branch 1 taken 6750663 times.
47254641 for(int32_t j=1; j<=6; j++)
1935 {
1936 40503978 mapscr* layer_scr = get_scr_layer_valid(screen, j);
1937
2/2
✓ Branch 0 taken 10894345 times.
✓ Branch 1 taken 29609633 times.
40503978 if (!layer_scr)
1938 29609633 continue;
1939
1940
2/2
✓ Branch 0 taken 1917404720 times.
✓ Branch 1 taken 10894345 times.
1928299065 for(int32_t i=0; i<176; i++)
1941 {
1942 1917404720 x=layer_scr->data[i];
1943 1917404720 auto& mini_cmb = combo_cache.minis[x];
1944
2/2
✓ Branch 0 taken 2230074 times.
✓ Branch 1 taken 1915174646 times.
1917404720 if (!mini_cmb.can_cycle)
1945 1915174646 continue;
1946
1947 2230074 newcombo const& cmb = combobuf[x];
1948
1949 //time to restart
1950
4/4
✓ Branch 0 taken 48416 times.
✓ Branch 1 taken 2181658 times.
✓ Branch 2 taken 37483 times.
✓ Branch 3 taken 10933 times.
2230074 if ((cmb.aclk>=cmb.speed) && combocheck(cmb))
1951 {
1952 10933 bool cycle_under = (cmb.animflags & AF_CYCLEUNDERCOMBO);
1953
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10933 times.
10933 auto c = cycle_under ? layer_scr->undercombo : cmb.nextcombo;
1954 10933 newdata[i] = c;
1955
2/2
✓ Branch 0 taken 69 times.
✓ Branch 1 taken 10864 times.
10933 if(!(cmb.animflags & AF_CYCLENOCSET))
1956
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10864 times.
10864 newcset[i] = cycle_under ? layer_scr->undercset : cmb.nextcset;
1957 69 else newcset[i] = layer_scr->cset[i];
1958
1959
2/2
✓ Branch 0 taken 950 times.
✓ Branch 1 taken 9983 times.
10933 if(combobuf[c].animflags & AF_CYCLE)
1960 {
1961 9983 restartanim.insert(c);
1962 9983 }
1963 10933 }
1964 2230074 }
1965
1966
2/2
✓ Branch 0 taken 1917404720 times.
✓ Branch 1 taken 10894345 times.
1928299065 for (int32_t i=0; i<176; i++)
1967 {
1968
2/2
✓ Branch 0 taken 1917393787 times.
✓ Branch 1 taken 10933 times.
1917404720 if(newdata[i]!=-1)
1969 {
1970 10933 layer_scr->data[i]=newdata[i];
1971
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10933 times.
10933 if(newcset[i]>-1)
1972 10933 layer_scr->cset[i]=newcset[i];
1973 10933 newdata[i]=-1;
1974 10933 newcset[i]=-1;
1975 10933 }
1976 1917404720 }
1977 10894345 }
1978 6750663 }
1979 15169062 });
1980
1981
2/2
✓ Branch 0 taken 14779694 times.
✓ Branch 1 taken 2661 times.
14782355 for (auto i : restartanim)
1982 {
1983 2661 combobuf[i].tile = combobuf[i].o_tile;
1984 2661 combobuf[i].cur_frame=0;
1985 2661 combobuf[i].aclk = 0;
1986
1/2
✓ Branch 0 taken 2661 times.
✗ Branch 1 not taken.
2661 combo_caches::drawing.refresh(i);
1987 }
1988 14779694 }
1989
1990 1209948096 bool iswater_type(int32_t type)
1991 {
1992 // return type==cOLD_WATER || type==cSWIMWARP || type==cDIVEWARP || type==cDIVEWARPB || type==cDIVEWARPC || type==cDIVEWARPD || type==cSWIMWARPB || type==cSWIMWARPC || type==cSWIMWARPD;
1993 1209948096 return (combo_class_buf[type].water!=0);
1994 }
1995
1996 bool iswater(int32_t combo)
1997 {
1998 return iswater_type(combobuf[combo].type) && !DRIEDLAKE;
1999 }
2000 1135408 int32_t iswaterexzq(int32_t combo, int32_t map, int32_t screen, int32_t layer, int32_t x, int32_t y, bool secrets, bool fullcheck, bool LayerCheck)
2001 {
2002 1135408 return iswaterex(combo, map, screen, layer, x, y, secrets, fullcheck, LayerCheck);
2003 }
2004
2005 // (x, y) are world coordinates
2006 58744740 int32_t iswaterex_z3(int32_t combo, int32_t layer, int32_t x, int32_t y, bool secrets, bool fullcheck, bool LayerCheck, bool ShallowCheck, bool hero, optional<combined_handle_t>* out_handle)
2007 {
2008
8/8
✓ Branch 0 taken 58698589 times.
✓ Branch 1 taken 46151 times.
✓ Branch 2 taken 58658257 times.
✓ Branch 3 taken 40332 times.
✓ Branch 4 taken 58591511 times.
✓ Branch 5 taken 66746 times.
✓ Branch 6 taken 59577 times.
✓ Branch 7 taken 58531934 times.
58744740 if (x<0 || x>=world_w || y<0 || y>=world_h)
2009 212806 return false;
2010
2011 58531934 return iswaterex(combo, cur_map, cur_screen, layer, x, y, secrets, fullcheck, LayerCheck, ShallowCheck, hero, out_handle);
2012 58744740 }
2013
2014 97205668 int32_t iswaterex(int32_t combo, int32_t map, int32_t screen, int32_t layer, int32_t x, int32_t y, bool secrets, bool fullcheck, bool LayerCheck, bool ShallowCheck, bool hero, optional<combined_handle_t>* out_handle)
2015 {
2016 DCHECK_LAYER_NEG1_INDEX(layer);
2017 //Honestly, fullcheck is kinda useless... I made this function back when I thought it was checking the entire combo and not just a glorified x/y value.
2018 //Fullcheck makes no sense to ever be on, but hey I guess it's here in case you ever need it...
2019
2020 //Oh hey, Zoras might actually need it. Nevermind, this had a use!
2021
2/2
✓ Branch 0 taken 57356207 times.
✓ Branch 1 taken 39849461 times.
97205668 if (get_qr(qr_SMARTER_WATER))
2022 {
2023
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 57356207 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
57356207 if (DRIEDLAKE) return 0;
2024
5/6
✓ Branch 0 taken 19560258 times.
✓ Branch 1 taken 37795949 times.
✓ Branch 2 taken 6518562 times.
✓ Branch 3 taken 13041696 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 6518562 times.
57356207 if (LayerCheck && (get_qr(qr_WATER_ON_LAYER_1) || get_qr(qr_WATER_ON_LAYER_2))) //LayerCheck is a bit dumber, but it lets me add this QR without having to replace all calls, again.
2025 {
2026
2/2
✓ Branch 0 taken 37778428 times.
✓ Branch 1 taken 12368366 times.
50146794 for (int32_t m = layer; m <= 1; m++)
2027 {
2028
5/6
✓ Branch 0 taken 24736732 times.
✓ Branch 1 taken 13041696 times.
✓ Branch 2 taken 12368366 times.
✓ Branch 3 taken 12368366 times.
✓ Branch 4 taken 12368366 times.
✗ Branch 5 not taken.
50146794 if (m < 0 || m == 0 && get_qr(qr_WATER_ON_LAYER_1)
2029
1/2
✓ Branch 0 taken 12368366 times.
✗ Branch 1 not taken.
24736732 || m == 1 && get_qr(qr_WATER_ON_LAYER_2))
2030 {
2031 37778428 int32_t checkwater = iswaterex(combo, map, screen, m, x, y, secrets, fullcheck, false, ShallowCheck);
2032
2/2
✓ Branch 0 taken 37105098 times.
✓ Branch 1 taken 673330 times.
37778428 if (checkwater > 0)
2033 {
2034
2/2
✓ Branch 0 taken 673272 times.
✓ Branch 1 taken 58 times.
673330 if(out_handle) *out_handle = get_rpos_handle_for_world_xy(x, y, m+1);
2035 673330 return checkwater;
2036 }
2037 37105098 }
2038 37105098 }
2039 12368366 return 0;
2040 }
2041 else
2042 {
2043
2/2
✓ Branch 0 taken 44329184 times.
✓ Branch 1 taken 42140357 times.
86469541 for(int32_t i=(fullcheck?3:0); i>=0; i--)
2044 {
2045 44329184 int32_t tx2=((i&2)<<2)+x;
2046 44329184 int32_t ty2=((i&1)<<3)+y;
2047 44329184 int32_t b = i; //Originally b was not needed and I read off i, but then I added the boolean for fullcheck.
2048 //In which case it's just easier to change b if fullcheck is false instead of changing i and potentially screwing up the for loop.
2049
2/2
✓ Branch 0 taken 21673 times.
✓ Branch 1 taken 44307511 times.
44329184 if (!fullcheck)
2050 {
2051 44307511 tx2 = x;
2052 44307511 ty2 = y;
2053
2/2
✓ Branch 0 taken 24876160 times.
✓ Branch 1 taken 19431351 times.
44307511 if(tx2&8) b+=2;
2054
2/2
✓ Branch 0 taken 20524614 times.
✓ Branch 1 taken 23782897 times.
44307511 if(ty2&8) b+=1;
2055 44307511 }
2056
2/2
✓ Branch 0 taken 94776242 times.
✓ Branch 1 taken 43484951 times.
138261193 for (int32_t m = layer; m <= 1; m++)
2057 {
2058 94776242 newcombo const& cmb = combobuf[MAPCOMBO3(map, screen, m,tx2,ty2, true)];
2059
2/2
✓ Branch 0 taken 17735727 times.
✓ Branch 1 taken 77040515 times.
94776242 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2060 {
2061
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 17735727 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
17735727 if (cmb.type == cBRIDGE && !(cmb.walk&(1<<b)))
2062 {
2063 return 0;
2064 }
2065 17735727 }
2066 else
2067 {
2068
4/4
✓ Branch 0 taken 179102 times.
✓ Branch 1 taken 76861413 times.
✓ Branch 2 taken 51152 times.
✓ Branch 3 taken 127950 times.
77040515 if (cmb.type == cBRIDGE && (cmb.walk&(0x10<<b)))
2069 {
2070 127950 return 0;
2071 }
2072 }
2073
2/2
✓ Branch 0 taken 17735727 times.
✓ Branch 1 taken 76912565 times.
94648292 if (get_qr(qr_NO_SOLID_SWIM))
2074 {
2075
8/14
✓ Branch 0 taken 51152 times.
✓ Branch 1 taken 76861413 times.
✓ Branch 2 taken 51152 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 716283 times.
✓ Branch 5 taken 76145130 times.
✓ Branch 6 taken 3461 times.
✓ Branch 7 taken 712822 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 3461 times.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
76912565 if ((cmb.type != cBRIDGE || (!get_qr(qr_OLD_BRIDGE_COMBOS) && !(cmb.walk&(0x10<<b)))) && (cmb.walk&(1<<b)) && !((cmb.usrflags&cflag4) && cmb.type == cWATER && (cmb.walk&(0x10<<b)) && ShallowCheck))
2076 {
2077 716283 return 0;
2078 }
2079 76196282 }
2080
3/6
✓ Branch 0 taken 320336 times.
✓ Branch 1 taken 93611673 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 320336 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
93932009 if (iswater_type(cmb.type) && (cmb.walk&(1<<b)) && ((cmb.usrflags&cflag3) || (cmb.usrflags&cflag4)
2081 || (hero && current_item(itype_flippers) < cmb.attribytes[0])
2082 || (hero && ((cmb.usrflags&cflag1) && !(itemsbuf[current_item_id(itype_flippers)].flags & item_flag3)))))
2083 {
2084 if (!(ShallowCheck && (cmb.walk&(1<<b)) && (cmb.usrflags&cflag4))) return 0;
2085 }
2086 93932009 }
2087
2088 131351511 auto found_ffc_not_water = find_ffc([&](const ffc_handle_t& ffc_handle) {
2089
2/2
✓ Branch 0 taken 87338695 times.
✓ Branch 1 taken 527865 times.
87866560 if (ffcIsAt(ffc_handle, tx2, ty2))
2090 {
2091 527865 auto ty = ffc_handle.ctype();
2092
4/6
✓ Branch 0 taken 527865 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 144225 times.
✓ Branch 3 taken 383640 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 144225 times.
527865 if(!combo_class_buf[ty].water && !(ShallowCheck && ty == cSHALLOWWATER))
2093 527865 return true;
2094 }
2095
2096 87338695 return false;
2097 87866560 });
2098
2/2
✓ Branch 0 taken 42957086 times.
✓ Branch 1 taken 527865 times.
43484951 if (found_ffc_not_water) return 0;
2099
2100
2/2
✓ Branch 0 taken 14673 times.
✓ Branch 1 taken 42942413 times.
42957086 if(!i)
2101 {
2102 127957187 auto found_ffc_water = find_ffc([&](const ffc_handle_t& ffc_handle) {
2103
1/2
✓ Branch 0 taken 85014774 times.
✗ Branch 1 not taken.
85014774 if (ffcIsAt(ffc_handle, tx2, ty2))
2104 {
2105 auto ty = ffc_handle.ctype();
2106 if(combo_class_buf[ty].water || (ShallowCheck && ty == cSHALLOWWATER))
2107 return true;
2108 }
2109
2110 85014774 return false;
2111 85014774 });
2112
1/2
✓ Branch 0 taken 42942413 times.
✗ Branch 1 not taken.
42942413 if (found_ffc_water)
2113 {
2114 if(out_handle) *out_handle = *found_ffc_water;
2115 return found_ffc_water->data();
2116 }
2117 42942413 }
2118
2119 42957086 int32_t checkcombo = MAPCOMBO3(map, screen, layer, tx2, ty2, secrets);
2120
2/2
✓ Branch 0 taken 42912592 times.
✓ Branch 1 taken 44494 times.
42957086 if (!(combobuf[checkcombo].walk&(1<<(b+4)))) return 0;
2121
7/12
✓ Branch 0 taken 42631987 times.
✓ Branch 1 taken 280605 times.
✓ Branch 2 taken 10830561 times.
✓ Branch 3 taken 31801426 times.
✓ Branch 4 taken 10352377 times.
✓ Branch 5 taken 478184 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 10352377 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
42912592 if (iswater_type(combobuf[checkcombo].type)||(ShallowCheck && (combobuf[checkcombo].type == cSHALLOWWATER || (iswater_type(combobuf[checkcombo].type) && (combobuf[checkcombo].walk&(1<<b)) && (combobuf[checkcombo].usrflags&cflag4)))))
2122 {
2123
2/2
✓ Branch 0 taken 1227 times.
✓ Branch 1 taken 757562 times.
758789 if (i == 0)
2124 {
2125
2/2
✓ Branch 0 taken 757553 times.
✓ Branch 1 taken 9 times.
757562 if(out_handle) *out_handle = get_rpos_handle_for_world_xy(tx2, ty2, layer+1);
2126 757562 return checkcombo;
2127 }
2128 1227 }
2129 42155030 }
2130 42140357 return 0;
2131 }
2132 }
2133 else
2134 {
2135 39849461 int32_t b = 0;
2136
2/2
✓ Branch 0 taken 20636412 times.
✓ Branch 1 taken 19213049 times.
39849461 if(x&8) b+=2;
2137
2/2
✓ Branch 0 taken 15456485 times.
✓ Branch 1 taken 24392976 times.
39849461 if(y&8) b+=1;
2138
1/2
✓ Branch 0 taken 39849461 times.
✗ Branch 1 not taken.
39849461 if (get_qr(qr_NO_SOLID_SWIM))
2139 {
2140 if (combobuf[combo].walk&(1<<b))
2141 {
2142 return 0;
2143 }
2144 }
2145
1/2
✓ Branch 0 taken 39849461 times.
✗ Branch 1 not taken.
39849461 if (!(combobuf[combo].walk&(1<<(b+4)))) return 0;
2146
8/8
✓ Branch 0 taken 38150901 times.
✓ Branch 1 taken 1698560 times.
✓ Branch 2 taken 167945 times.
✓ Branch 3 taken 37982956 times.
✓ Branch 4 taken 2129 times.
✓ Branch 5 taken 1782338 times.
✓ Branch 6 taken 163774 times.
✓ Branch 7 taken 161691 times.
39849461 if((iswater_type(combobuf[combo].type) || (ShallowCheck && combobuf[combo].type == cSHALLOWWATER)) && !DRIEDLAKE)
2147 {
2148
2/2
✓ Branch 0 taken 1943999 times.
✓ Branch 1 taken 30 times.
1944029 if(out_handle) *out_handle = get_rpos_handle_for_world_xy(x, y, 0); //NOTE: This is only correct assuming 'combo' is 'MAPCOMBO(x,y)'
2149 1944029 return combo;
2150 }
2151 38146730 return 0;
2152 }
2153 97446966 }
2154
2155 326 bool isdamage_type(int32_t type)
2156 {
2157
1/2
✓ Branch 0 taken 326 times.
✗ Branch 1 not taken.
326 switch(type)
2158 {
2159 case cDAMAGE1: case cDAMAGE2: case cDAMAGE3: case cDAMAGE4:
2160 case cDAMAGE5: case cDAMAGE6: case cDAMAGE7:
2161 return true;
2162 }
2163 326 return false;
2164 326 }
2165
2166 2569347297 bool ispitfall_type(int32_t type)
2167 {
2168 2569347297 return combo_class_buf[type].pit != 0;
2169 }
2170
2171 2569347297 bool ispitfall(int32_t combo)
2172 {
2173 2569347297 return ispitfall_type(combobuf[combo].type);
2174 }
2175
2176 278127958 bool ispitfall(int32_t x, int32_t y)
2177 {
2178
2/2
✓ Branch 0 taken 1456039 times.
✓ Branch 1 taken 276671919 times.
278127958 if(int32_t c = MAPFFCOMBO(x,y))
2179 {
2180 1456039 return ispitfall(c) ? true : false;
2181 }
2182 276671919 int32_t c = MAPCOMBOL(2,x,y);
2183
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 276671919 times.
276671919 if(ispitfall(c)) return true;
2184
2/2
✓ Branch 0 taken 263560767 times.
✓ Branch 1 taken 13111152 times.
276671919 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2185 {
2186
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 263560767 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
263560767 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,1)) return false;
2187 263560767 }
2188 else
2189 {
2190
3/4
✓ Branch 0 taken 2780 times.
✓ Branch 1 taken 13108372 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2780 times.
13111152 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && _effectflag_layer(x,y,1)) return false;
2191 }
2192 276669139 c = MAPCOMBOL(1,x,y);
2193
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 276669115 times.
276669139 if(ispitfall(c)) return true;
2194
2195
2/2
✓ Branch 0 taken 263560767 times.
✓ Branch 1 taken 13108348 times.
276669115 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2196 {
2197
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 263560767 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
263560767 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,0)) return false;
2198 263560767 }
2199 else
2200 {
2201
4/4
✓ Branch 0 taken 13072 times.
✓ Branch 1 taken 13095276 times.
✓ Branch 2 taken 8777 times.
✓ Branch 3 taken 4295 times.
13108348 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && _effectflag_layer(x,y,0)) return false;
2202 }
2203 276660338 c = MAPCOMBO(x,y);
2204
2/2
✓ Branch 0 taken 70747 times.
✓ Branch 1 taken 276589591 times.
276660338 if(ispitfall(c)) return true;
2205 276589591 return false;
2206 278127958 }
2207
2208 585542416 int32_t getpitfall(int32_t x, int32_t y) //Return the highest-layer active pit combo at the given position
2209 {
2210
2/2
✓ Branch 0 taken 9281019 times.
✓ Branch 1 taken 576261397 times.
585542416 if(int32_t c = MAPFFCOMBO(x,y))
2211 {
2212
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9281019 times.
9281019 return ispitfall(c) ? c : 0;
2213 }
2214 576261397 int32_t c = MAPCOMBOL(2,x,y);
2215
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 576261397 times.
576261397 if(ispitfall(c)) return c;
2216
2217
2/2
✓ Branch 0 taken 532722485 times.
✓ Branch 1 taken 43538912 times.
576261397 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2218 {
2219
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 532722485 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
532722485 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,1)) return 0;
2220 532722485 }
2221 else
2222 {
2223
3/4
✓ Branch 0 taken 35747 times.
✓ Branch 1 taken 43503165 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 35747 times.
43538912 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && _effectflag_layer(x,y,1)) return 0;
2224 }
2225 576225650 c = MAPCOMBOL(1,x,y);
2226
2/2
✓ Branch 0 taken 278 times.
✓ Branch 1 taken 576225372 times.
576225650 if(ispitfall(c)) return c;
2227
2228
2/2
✓ Branch 0 taken 532722485 times.
✓ Branch 1 taken 43502887 times.
576225372 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2229 {
2230
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 532722485 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
532722485 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,0)) return 0;
2231 532722485 }
2232 else
2233 {
2234
4/4
✓ Branch 0 taken 144357 times.
✓ Branch 1 taken 43358530 times.
✓ Branch 2 taken 103729 times.
✓ Branch 3 taken 40628 times.
43502887 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && _effectflag_layer(x,y,0)) return 0;
2235 }
2236 576121643 c = MAPCOMBO(x,y);
2237
2/2
✓ Branch 0 taken 176844 times.
✓ Branch 1 taken 575944799 times.
576121643 if(ispitfall(c)) return c;
2238 575944799 return 0;
2239 585542416 }
2240 51 optional<combined_handle_t> get_pitfall_handle(int32_t x, int32_t y) //Return the highest-layer active pit combo handle at the given position
2241 {
2242
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 51 times.
51 if(int32_t c = MAPFFCOMBO(x,y))
2243 {
2244 return ispitfall(c) ? getFFCAt(x,y) : nullopt;
2245 }
2246 51 int32_t c = MAPCOMBOL(2,x,y);
2247
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 51 times.
51 if(ispitfall(c)) return get_rpos_handle_for_world_xy(x, y, 2);
2248
2249
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 45 times.
51 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2250 {
2251
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
6 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,1))
2252 return nullopt;
2253 6 }
2254 else
2255 {
2256
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 45 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
45 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && _effectflag_layer(x,y,1))
2257 return nullopt;
2258 }
2259 51 c = MAPCOMBOL(1,x,y);
2260
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 51 times.
51 if(ispitfall(c)) return get_rpos_handle_for_world_xy(x, y, 1);
2261
2262
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 45 times.
51 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2263 {
2264
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
6 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,0))
2265 return nullopt;
2266 6 }
2267 else
2268 {
2269
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 45 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
45 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && _effectflag_layer(x,y,0))
2270 return nullopt;
2271 }
2272 51 c = MAPCOMBO(x,y);
2273
1/2
✓ Branch 0 taken 51 times.
✗ Branch 1 not taken.
51 if(ispitfall(c)) return get_rpos_handle_for_world_xy(x, y, 0);
2274 return nullopt;
2275 51 }
2276 5426640 bool check_icy(newcombo const& cmb, int type)
2277 {
2278
2/2
✓ Branch 0 taken 5426475 times.
✓ Branch 1 taken 165 times.
5426640 if(cmb.type != cICY)
2279 5426475 return false;
2280
1/3
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 165 times.
165 switch(type)
2281 {
2282 case ICY_BLOCK:
2283 return cmb.usrflags&cflag1;
2284 case ICY_PLAYER:
2285 165 return cmb.usrflags&cflag2;
2286 }
2287 return false;
2288 5426640 }
2289 1811404 int get_icy(int x, int y, int type)
2290 {
2291 1811404 int32_t c = MAPCOMBOL(2,x,y);
2292
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1811404 times.
1811404 if(check_icy(combobuf[c], type)) return c;
2293
2294 1811404 int screen = get_screen_for_world_xy(x, y);
2295
2296 1811404 mapscr* scr = get_scr_layer_valid(screen, 2);
2297
2/2
✓ Branch 0 taken 430769 times.
✓ Branch 1 taken 1380635 times.
1811404 if (scr)
2298 {
2299
2/2
✓ Branch 0 taken 516 times.
✓ Branch 1 taken 1380119 times.
1380635 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2300 {
2301
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 516 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
516 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,1, scr)) return 0;
2302 516 }
2303 else
2304 {
2305
3/4
✓ Branch 0 taken 3048 times.
✓ Branch 1 taken 1377071 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3048 times.
1380119 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && _effectflag_layer(x,y,1, scr)) return 0;
2306 }
2307 1377587 }
2308 1808356 c = MAPCOMBOL(1,x,y);
2309
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1808356 times.
1808356 if(check_icy(combobuf[c], type)) return c;
2310
2311 1808356 scr = get_scr_layer_valid(screen, 1);
2312
2/2
✓ Branch 0 taken 73612 times.
✓ Branch 1 taken 1734744 times.
1808356 if (scr)
2313 {
2314
2/2
✓ Branch 0 taken 1934 times.
✓ Branch 1 taken 1732810 times.
1734744 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2315 {
2316
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1934 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1934 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,1, scr)) return 0;
2317 1934 }
2318 else
2319 {
2320
3/4
✓ Branch 0 taken 1641 times.
✓ Branch 1 taken 1731169 times.
✓ Branch 2 taken 1641 times.
✗ Branch 3 not taken.
1732810 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && _effectflag_layer(x,y,1, scr)) return 0;
2321 }
2322 1733103 }
2323 1806715 c = MAPCOMBO(x,y);
2324
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1806715 times.
1806715 if(check_icy(combobuf[c], type)) return c;
2325 1806715 return 0;
2326 1811404 }
2327
2328 13049036 static bool checkSV(int32_t x, int32_t y, int32_t flag)
2329 {
2330
8/8
✓ Branch 0 taken 13042238 times.
✓ Branch 1 taken 6798 times.
✓ Branch 2 taken 13033372 times.
✓ Branch 3 taken 8866 times.
✓ Branch 4 taken 13021740 times.
✓ Branch 5 taken 11632 times.
✓ Branch 6 taken 428468 times.
✓ Branch 7 taken 12593272 times.
13049036 if(x<0 || x>=world_w || y<0 || y>=world_h)
2331 455764 return false;
2332
2333 12593272 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, 0);
2334
2/4
✓ Branch 0 taken 12593272 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 12593272 times.
12593272 if (rpos_handle.sflag() == flag || rpos_handle.cflag() == flag)
2335 return true;
2336
2337 12593272 change_rpos_handle_layer(rpos_handle, 1);
2338
2/2
✓ Branch 0 taken 7565562 times.
✓ Branch 1 taken 5027710 times.
12593272 if (rpos_handle.scr->is_valid())
2339
3/4
✓ Branch 0 taken 5027710 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3279 times.
✓ Branch 3 taken 5024431 times.
5027710 if (rpos_handle.sflag() == flag || rpos_handle.cflag() == flag)
2340 3279 return true;
2341
2342 12589993 change_rpos_handle_layer(rpos_handle, 2);
2343
2/2
✓ Branch 0 taken 10876856 times.
✓ Branch 1 taken 1713137 times.
12589993 if (rpos_handle.scr->is_valid())
2344
2/4
✓ Branch 0 taken 1713137 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1713137 times.
1713137 if (rpos_handle.sflag() == flag || rpos_handle.cflag() == flag)
2345 return true;
2346
2347 12589993 return false;
2348 13049036 }
2349
2350 6588680 bool isSVLadder(int32_t x, int32_t y)
2351 {
2352 6588680 return checkSV(x, y, mfSIDEVIEWLADDER);
2353 }
2354
2355 6460356 bool isSVPlatform(int32_t x, int32_t y)
2356 {
2357 6460356 return checkSV(x, y, mfSIDEVIEWPLATFORM);
2358 }
2359
2360 6460356 bool checkSVLadderPlatform(int32_t x, int32_t y)
2361 {
2362
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 6460356 times.
✓ Branch 2 taken 6458559 times.
✓ Branch 3 taken 1797 times.
6460356 return isSVPlatform(x,y) || (isSVLadder(x,y) && !isSVLadder(x,y-16));
2363 }
2364
2365 1637 bool isstepable(int32_t combo) //can use ladder on it
2366 {
2367
2/2
✓ Branch 0 taken 1631 times.
✓ Branch 1 taken 6 times.
1637 if(combo_class_buf[combobuf[combo].type].ladder_pass) return true;
2368
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 if(combo_class_buf[combobuf[combo].type].pit)
2369 {
2370 if(combobuf[combo].usrflags&cflag4)
2371 {
2372 int32_t ldrid = current_item_id(itype_ladder);
2373 return (ldrid > -1 && itemsbuf[ldrid].flags & item_flag1);
2374 }
2375 }
2376 6 return false;
2377 1637 }
2378
2379 32780 bool isHSGrabbable(newcombo const& cmb)
2380 {
2381
2/2
✓ Branch 0 taken 373 times.
✓ Branch 1 taken 32407 times.
32780 if(cmb.type == cHSGRAB) return true;
2382 32407 return cmb.genflags & cflag1;
2383 32780 }
2384
2385 954 bool isSwitchHookable(newcombo const& cmb)
2386 {
2387
2/2
✓ Branch 0 taken 132 times.
✓ Branch 1 taken 822 times.
954 if(cmb.type == cSWITCHHOOK) return true;
2388 822 return cmb.genflags & cflag2;
2389 954 }
2390
2391 61401 bool check_hshot(int32_t layer, int32_t x, int32_t y, bool switchhook, rpos_t *out_rpos, ffcdata **out_ffc)
2392 {
2393 61401 rpos_t cpos = rpos_t::None;
2394
2/2
✓ Branch 0 taken 64592 times.
✓ Branch 1 taken 125993 times.
61401 if(out_rpos)
2395 {
2396 125993 int32_t id = MAPCOMBO2(layer-1,x,y);
2397
2/2
✓ Branch 0 taken 28634 times.
✓ Branch 1 taken 97359 times.
125993 if(id > 0)
2398 {
2399 97359 newcombo const& cmb = combobuf[id];
2400
4/4
✓ Branch 0 taken 32738 times.
✓ Branch 1 taken 64621 times.
✓ Branch 2 taken 32296 times.
✓ Branch 3 taken 32325 times.
97359 cpos = (switchhook ? isSwitchHookable(cmb) : isHSGrabbable(cmb)) ? COMBOPOS_REGION(x,y) : rpos_t::None;
2401 32767 }
2402 61401 }
2403
2404 125993 ffcdata* ffc = nullptr;
2405
4/4
✓ Branch 0 taken 28389 times.
✓ Branch 1 taken 97604 times.
✓ Branch 2 taken 24996 times.
✓ Branch 3 taken 3393 times.
125993 if (out_ffc && !get_qr(qr_OLD_FFC_FUNCTIONALITY))
2406 {
2407 10359 for_some_ffcs([&](const ffc_handle_t& ffc_handle) {
2408
2/2
✓ Branch 0 taken 6853 times.
✓ Branch 1 taken 113 times.
6966 if (ffcIsAt(ffc_handle, x, y))
2409 {
2410 113 auto& cmb = ffc_handle.combo();
2411
4/4
✓ Branch 0 taken 42 times.
✓ Branch 1 taken 71 times.
✓ Branch 2 taken 35 times.
✓ Branch 3 taken 36 times.
113 if (switchhook ? isSwitchHookable(cmb) : isHSGrabbable(cmb))
2412 {
2413 77 ffc = ffc_handle.ffc;
2414 77 return false;
2415 }
2416 36 }
2417 6889 return true;
2418 6896 });
2419 3393 }
2420
2421
4/4
✓ Branch 0 taken 61401 times.
✓ Branch 1 taken 64592 times.
✓ Branch 2 taken 442 times.
✓ Branch 3 taken 60959 times.
125993 if (out_rpos && cpos != rpos_t::None) *out_rpos = cpos;
2422
4/4
✓ Branch 0 taken 28389 times.
✓ Branch 1 taken 97604 times.
✓ Branch 2 taken 7 times.
✓ Branch 3 taken 28382 times.
125993 if (out_ffc && ffc) *out_ffc = ffc;
2423
2/2
✓ Branch 0 taken 65034 times.
✓ Branch 1 taken 60959 times.
125993 return (cpos != rpos_t::None || ffc);
2424 }
2425
2426 5195 bool ishookshottable(int32_t bx, int32_t by)
2427 {
2428
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5195 times.
5195 if(!_walkflag(bx,by,1))
2429 return true;
2430
2431
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5187 times.
5195 if (collide_object(bx, by, 1, 1))
2432 8 return false;
2433
2434 5187 bool ret = true;
2435
2/2
✓ Branch 0 taken 15561 times.
✓ Branch 1 taken 1900 times.
17461 for(int32_t i=2; i>=0; i--)
2436 {
2437 15561 int32_t c = MAPCOMBO2(i-1,bx,by);
2438 15561 int32_t t = combobuf[c].type;
2439
2440
6/6
✓ Branch 0 taken 5187 times.
✓ Branch 1 taken 10374 times.
✓ Branch 2 taken 3853 times.
✓ Branch 3 taken 1334 times.
✓ Branch 4 taken 1900 times.
✓ Branch 5 taken 1953 times.
15561 if(i == 0 && (t == cHOOKSHOTONLY || t == cLADDERHOOKSHOT)) return true;
2441
2442
3/4
✓ Branch 0 taken 11321 times.
✓ Branch 1 taken 953 times.
✓ Branch 2 taken 953 times.
✗ Branch 3 not taken.
13227 bool dried = (iswater_type(t) && DRIEDLAKE);
2443
2444 12274 int32_t b=1;
2445
2446
2/2
✓ Branch 0 taken 6109 times.
✓ Branch 1 taken 6165 times.
12274 if(bx&8) b<<=2;
2447
2448
2/2
✓ Branch 0 taken 3841 times.
✓ Branch 1 taken 8433 times.
12274 if(by&8) b<<=1;
2449
2450
7/8
✓ Branch 0 taken 2094 times.
✓ Branch 1 taken 10180 times.
✓ Branch 2 taken 2094 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1115 times.
✓ Branch 5 taken 979 times.
✓ Branch 6 taken 75 times.
✓ Branch 7 taken 904 times.
12274 if(combobuf[c].walk&b && !dried && !(combo_class_buf[t].ladder_pass && t!=cLADDERONLY) && t!=cHOOKSHOTONLY)
2451 904 ret = false;
2452 12274 }
2453
2454 1900 return ret;
2455 5195 }
2456
2457 10110 bool reveal_hidden_stairs(mapscr *s, int32_t screen, bool redraw)
2458 {
2459
4/4
✓ Branch 0 taken 9531 times.
✓ Branch 1 taken 579 times.
✓ Branch 2 taken 9531 times.
✓ Branch 3 taken 579 times.
10110 if((s->stairx || s->stairy) && s->secretcombo[sSTAIRS])
2460 {
2461 579 int pos = COMBOPOS(s->stairx,s->stairy);
2462 579 s->data[pos] = s->secretcombo[sSTAIRS];
2463 579 s->cset[pos] = s->secretcset[sSTAIRS];
2464 579 s->sflag[pos] = s->secretflag[sSTAIRS];
2465
2466
2/2
✓ Branch 0 taken 256 times.
✓ Branch 1 taken 323 times.
579 if (redraw)
2467 {
2468 768 auto [x, y] = translate_screen_coordinates_to_world(screen, s->stairx, s->stairy);
2469 768 putcombo(scrollbuf,x,y,s->data[pos],s->cset[pos]);
2470 256 }
2471
2472 579 return true;
2473 }
2474
2475 9531 return false;
2476 10110 }
2477
2478 51768 screen_handles_t create_screen_handles_one(mapscr* base_scr)
2479 {
2480 DCHECK(base_scr->is_valid());
2481
2482 51768 screen_handles_t screen_handles{};
2483 51768 screen_handles[0] = {base_scr, base_scr, base_scr->screen, 0};
2484 51768 return screen_handles;
2485 }
2486
2487 56531351 screen_handles_t create_screen_handles(mapscr* base_scr)
2488 {
2489 DCHECK(get_scr(base_scr->screen) == base_scr);
2490 DCHECK(base_scr->is_valid());
2491
2492 56531351 int screen = base_scr->screen;
2493 screen_handles_t screen_handles;
2494 56531351 screen_handles[0] = {base_scr, base_scr, screen, 0};
2495
2/2
✓ Branch 0 taken 339188106 times.
✓ Branch 1 taken 56531351 times.
395719457 for (int i = 1; i <= 6; i++)
2496 339188106 screen_handles[i] = {base_scr, get_scr_layer_valid(screen, i), screen, i};
2497 56531351 return screen_handles;
2498 }
2499
2500 106202 bool remove_screenstatecombos2(const screen_handles_t& screen_handles, bool do_layers, int32_t what1, int32_t what2)
2501 {
2502 106202 mapscr* scr = screen_handles[0].scr;
2503 106202 bool didit=false;
2504
2505
2/2
✓ Branch 0 taken 106202 times.
✓ Branch 1 taken 18691552 times.
18797754 for(int32_t i=0; i<176; i++)
2506 {
2507 18691552 newcombo const& cmb = combobuf[scr->data[i]];
2508
2/2
✓ Branch 0 taken 326 times.
✓ Branch 1 taken 18691226 times.
18691552 if(cmb.usrflags&cflag16) continue; //custom state instead of normal state
2509
4/4
✓ Branch 0 taken 18689693 times.
✓ Branch 1 taken 1533 times.
✓ Branch 2 taken 1102 times.
✓ Branch 3 taken 18688591 times.
18691226 if((cmb.type == what1) || (cmb.type== what2))
2510 {
2511 2635 scr->data[i]++;
2512 2635 didit=true;
2513 2635 }
2514 18691226 }
2515
2516
2/2
✓ Branch 0 taken 92 times.
✓ Branch 1 taken 106110 times.
106202 if (do_layers)
2517 {
2518
2/2
✓ Branch 0 taken 636660 times.
✓ Branch 1 taken 106110 times.
742770 for(int32_t j=1; j<=6; j++)
2519 {
2520 636660 mapscr* layer_scr = screen_handles[j].scr;
2521
2/2
✓ Branch 0 taken 173044 times.
✓ Branch 1 taken 463616 times.
636660 if (!layer_scr) continue;
2522
2523
2/2
✓ Branch 0 taken 30455744 times.
✓ Branch 1 taken 173044 times.
30628788 for(int32_t i=0; i<176; i++)
2524 {
2525 30455744 newcombo const& cmb = combobuf[layer_scr->data[i]];
2526
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 30455744 times.
30455744 if(cmb.usrflags&cflag16) continue; //custom state instead of normal state
2527
4/4
✓ Branch 0 taken 30455661 times.
✓ Branch 1 taken 83 times.
✓ Branch 2 taken 265 times.
✓ Branch 3 taken 30455396 times.
30455744 if((cmb.type== what1) || (cmb.type== what2))
2528 {
2529 348 layer_scr->data[i]++;
2530 348 didit=true;
2531 348 }
2532 30455744 }
2533 173044 }
2534 106110 }
2535
2536 // 'do_layers' also means that this is called on an active temp screen, so update its ffcs.
2537
3/4
✓ Branch 0 taken 20406 times.
✓ Branch 1 taken 85796 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 20406 times.
106202 if (!get_qr(qr_OLD_FFC_FUNCTIONALITY) && do_layers)
2538 {
2539 20406 word c = scr->numFFC();
2540
2/2
✓ Branch 0 taken 73350 times.
✓ Branch 1 taken 20406 times.
93756 for(word i=0; i<c; i++)
2541 {
2542 73350 ffcdata* ffc = &scr->ffcs[i];
2543 73350 newcombo const& cmb = combobuf[ffc->data];
2544
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 73350 times.
73350 if(cmb.usrflags&cflag16) continue; //custom state instead of normal state
2545
2/4
✓ Branch 0 taken 73350 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 73350 times.
73350 if((cmb.type== what1) || (cmb.type== what2))
2546 {
2547 zc_ffc_modify(*ffc, 1);
2548 didit=true;
2549 }
2550 73350 }
2551 20406 }
2552
2553 106202 return didit;
2554 }
2555
2556 14 bool remove_xstatecombos(const screen_handles_t& screen_handles, byte xflag, bool triggers)
2557 {
2558 14 int screen = screen_handles[0].scr->screen;
2559
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
14 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
2560 14 return remove_xstatecombos_mi(screen_handles, mi, xflag, triggers);
2561 }
2562 471496206 bool remove_xstatecombos_mi(const screen_handles_t& screen_handles, int32_t mi, byte xflag, bool triggers)
2563 {
2564 471496206 bool didit=false;
2565
2/2
✓ Branch 0 taken 471467348 times.
✓ Branch 1 taken 28858 times.
471496206 if(!getxmapflag_mi(mi, 1<<xflag)) return false;
2566
2567 28858 mapscr* s = screen_handles[0].scr;
2568 28858 int screen = s->screen;
2569 28858 bool is_active_screen = is_in_current_region(s);
2570
2571 24248394 for_every_rpos_in_screen(screen_handles, [&](const rpos_handle_t& rpos_handle) {
2572
4/4
✓ Branch 0 taken 24207920 times.
✓ Branch 1 taken 11616 times.
✓ Branch 2 taken 24206112 times.
✓ Branch 3 taken 1808 times.
24219536 if(triggers && force_ex_trigger_any(rpos_handle, xflag))
2573 1808 didit = true;
2574
2/2
✓ Branch 0 taken 63627 times.
✓ Branch 1 taken 24154101 times.
24217728 else switch (rpos_handle.ctype())
2575 {
2576 case cLOCKBLOCK: case cLOCKBLOCK2:
2577 case cBOSSLOCKBLOCK: case cBOSSLOCKBLOCK2:
2578 case cCHEST: case cCHEST2:
2579 case cLOCKEDCHEST: case cLOCKEDCHEST2:
2580 case cBOSSCHEST: case cBOSSCHEST2:
2581 {
2582 63627 auto& cmb = rpos_handle.combo();
2583
2/2
✓ Branch 0 taken 62059 times.
✓ Branch 1 taken 1568 times.
63627 if(!(cmb.usrflags&cflag16)) return; //custom state instead of normal state
2584
2/2
✓ Branch 0 taken 29 times.
✓ Branch 1 taken 62030 times.
62059 if(cmb.attribytes[5] == xflag)
2585 {
2586 29 rpos_handle.increment_data();
2587 29 didit=true;
2588 29 }
2589 62059 break;
2590 }
2591 }
2592 24219536 });
2593
2594
4/4
✓ Branch 0 taken 28817 times.
✓ Branch 1 taken 41 times.
✓ Branch 2 taken 19197 times.
✓ Branch 3 taken 9620 times.
28858 if (is_active_screen && !get_qr(qr_OLD_FFC_FUNCTIONALITY))
2595 {
2596 19197 word c = s->numFFC();
2597 19197 int screen_index_offset = get_region_screen_offset(screen);
2598
2/2
✓ Branch 0 taken 36840 times.
✓ Branch 1 taken 19197 times.
56037 for (uint8_t i = 0; i < c; i++)
2599 {
2600 36840 auto ffc_handle = *s->getFFCHandle(i, screen_index_offset);
2601 36840 auto& cmb = ffc_handle.combo();
2602
3/4
✓ Branch 0 taken 36840 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 36824 times.
✓ Branch 3 taken 16 times.
36840 if(triggers && force_ex_trigger_ffc_any(ffc_handle, xflag))
2603 16 didit = true;
2604
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 36824 times.
36824 else switch(cmb.type)
2605 {
2606 case cLOCKBLOCK: case cLOCKBLOCK2:
2607 case cBOSSLOCKBLOCK: case cBOSSLOCKBLOCK2:
2608 case cCHEST: case cCHEST2:
2609 case cLOCKEDCHEST: case cLOCKEDCHEST2:
2610 case cBOSSCHEST: case cBOSSCHEST2:
2611 {
2612 if(!(cmb.usrflags&cflag16)) continue; //custom state instead of normal state
2613 if(cmb.attribytes[5] == xflag)
2614 {
2615 zc_ffc_modify(*ffc_handle.ffc, 1);
2616 didit=true;
2617 }
2618 break;
2619 }
2620 }
2621 36840 }
2622 19197 }
2623
2624 28858 return didit;
2625 471496206 }
2626
2627 14682265 void clear_xstatecombos(const screen_handles_t& screen_handles, bool triggers)
2628 {
2629 14682265 int screen = screen_handles[0].screen;
2630
2/2
✓ Branch 0 taken 387833 times.
✓ Branch 1 taken 14294432 times.
14682265 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
2631 14682265 clear_xstatecombos_mi(screen_handles, mi, triggers);
2632 14682265 }
2633
2634 14734256 void clear_xstatecombos_mi(const screen_handles_t& screen_handles, int32_t mi, bool triggers)
2635 {
2636
2/2
✓ Branch 0 taken 471496192 times.
✓ Branch 1 taken 14734256 times.
486230448 for (int q = 0; q < 32; ++q)
2637 {
2638 471496192 remove_xstatecombos_mi(screen_handles, mi, q, triggers);
2639 471496192 }
2640 14734256 }
2641
2642 bool remove_xdoors(const screen_handles_t& screen_handles, uint dir, uint ind, bool triggers)
2643 {
2644 int screen = screen_handles[0].screen;
2645 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
2646 return remove_xdoors_mi(screen_handles, mi, dir, ind, triggers);
2647 }
2648 471496192 bool remove_xdoors_mi(const screen_handles_t& screen_handles, int32_t mi, uint dir, uint ind, bool triggers)
2649 {
2650 471496192 bool didit=false;
2651
2/2
✓ Branch 0 taken 471494879 times.
✓ Branch 1 taken 1313 times.
471496192 if (!getxdoor_mi(mi, dir, ind)) return false;
2652
2653 1313 mapscr* scr = screen_handles[0].scr;
2654 1313 int screen = scr->screen;
2655 1313 bool is_active_screen = is_in_current_region(scr);
2656
2657 925665 for_every_rpos_in_screen(screen_handles, [&](const rpos_handle_t& rpos_handle) {
2658
3/4
✓ Branch 0 taken 924352 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11 times.
✓ Branch 3 taken 924341 times.
924352 if (triggers && force_ex_door_trigger_any(rpos_handle, dir, ind))
2659 11 didit = true;
2660 else; //future door combo types?
2661 924352 });
2662
2663
2/4
✓ Branch 0 taken 1313 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1313 times.
✗ Branch 3 not taken.
1313 if (!get_qr(qr_OLD_FFC_FUNCTIONALITY) && is_active_screen)
2664 {
2665 1313 word c = scr->numFFC();
2666 1313 int screen_index_offset = get_region_screen_offset(screen);
2667
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1313 times.
1313 for (uint8_t i = 0; i < c; i++)
2668 {
2669 auto ffc_handle = *scr->getFFCHandle(i, screen_index_offset);
2670 if (triggers && force_ex_door_trigger_ffc_any(ffc_handle, dir, ind))
2671 didit = true;
2672 else; //future door combo types?
2673 }
2674 1313 }
2675
2676 1313 return didit;
2677 471496192 }
2678
2679 14682265 void clear_xdoors(const screen_handles_t& screen_handles, bool triggers)
2680 {
2681 14682265 int screen = screen_handles[0].screen;
2682
2/2
✓ Branch 0 taken 387833 times.
✓ Branch 1 taken 14294432 times.
14682265 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
2683 14682265 return clear_xdoors_mi(screen_handles, mi, triggers);
2684 }
2685
2686 14734256 void clear_xdoors_mi(const screen_handles_t& screen_handles, int32_t mi, bool triggers)
2687 {
2688
2/2
✓ Branch 0 taken 58937024 times.
✓ Branch 1 taken 14734256 times.
73671280 for (int dir = 0; dir < 4; ++dir)
2689
2/2
✓ Branch 0 taken 471496192 times.
✓ Branch 1 taken 58937024 times.
530433216 for (int q = 0; q < 8; ++q)
2690 530433216 remove_xdoors_mi(screen_handles, mi, dir, q, triggers);
2691 14734256 }
2692
2693 763 bool remove_lockblocks(const screen_handles_t& screen_handles)
2694 {
2695 763 return remove_screenstatecombos2(screen_handles, true, cLOCKBLOCK, cLOCKBLOCK2);
2696 }
2697
2698 98 bool remove_bosslockblocks(const screen_handles_t& screen_handles)
2699 {
2700 98 return remove_screenstatecombos2(screen_handles, true, cBOSSLOCKBLOCK, cBOSSLOCKBLOCK2);
2701 }
2702
2703 76553 bool remove_chests(const screen_handles_t& screen_handles)
2704 {
2705 76553 return remove_screenstatecombos2(screen_handles, true, cCHEST, cCHEST2);
2706 }
2707
2708 2484 bool remove_lockedchests(const screen_handles_t& screen_handles)
2709 {
2710 2484 return remove_screenstatecombos2(screen_handles, true, cLOCKEDCHEST, cLOCKEDCHEST2);
2711 }
2712
2713 26212 bool remove_bosschests(const screen_handles_t& screen_handles)
2714 {
2715 26212 return remove_screenstatecombos2(screen_handles, true, cBOSSCHEST, cBOSSCHEST2);
2716 }
2717
2718 1384361 void delete_fireball_shooter(const rpos_handle_t& rpos_handle)
2719 {
2720 1384361 int32_t ct=rpos_handle.ctype();
2721
2722
6/6
✓ Branch 0 taken 1383741 times.
✓ Branch 1 taken 620 times.
✓ Branch 2 taken 1383489 times.
✓ Branch 3 taken 252 times.
✓ Branch 4 taken 1383381 times.
✓ Branch 5 taken 108 times.
1384361 if(ct!=cL_STATUE && ct!=cR_STATUE && ct!=cC_STATUE)
2723 1383381 return;
2724
2725 2465 auto [cx, cy] = rpos_handle.xy();
2726
3/4
✓ Branch 0 taken 252 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 620 times.
✓ Branch 3 taken 108 times.
980 switch(ct)
2727 {
2728 case cL_STATUE:
2729 620 cx += 4;
2730 620 cy += 7;
2731 620 break;
2732
2733 case cR_STATUE:
2734 252 cx -= 8;
2735 252 cy -= 1;
2736 252 break;
2737
2738 case cC_STATUE:
2739 108 break;
2740 }
2741
2742
2/2
✓ Branch 0 taken 980 times.
✓ Branch 1 taken 1485 times.
2465 for(int32_t j=0; j<guys.Count(); j++)
2743 {
2744 // Finds the smallest enemy ID
2745
9/10
✓ Branch 0 taken 399 times.
✓ Branch 1 taken 1086 times.
✓ Branch 2 taken 399 times.
✓ Branch 3 taken 1086 times.
✓ Branch 4 taken 346 times.
✓ Branch 5 taken 53 times.
✓ Branch 6 taken 346 times.
✓ Branch 7 taken 53 times.
✓ Branch 8 taken 346 times.
✗ Branch 9 not taken.
2970 if((int32_t(guys.spr(j)->x)==cx)&&(int32_t(guys.spr(j)->y)==cy)&&(guysbuf[(guys.spr(j)->id)&0xFFF].flags & guy_fire))
2746 {
2747 346 guys.del(j);
2748 346 }
2749 1485 }
2750 1384361 }
2751
2752 15 static int32_t findtrigger(int32_t screen)
2753 {
2754 15 int32_t checkflag=0;
2755 15 int32_t ret = 0;
2756
2757 mapscr* screens[7];
2758
2/2
✓ Branch 0 taken 105 times.
✓ Branch 1 taken 15 times.
120 for (int32_t j = 0; j <= 6; j++)
2759 {
2760 105 screens[j] = get_scr_layer_valid(screen, j);
2761 105 }
2762
2763 15 bool sflag = false;
2764
2/2
✓ Branch 0 taken 2640 times.
✓ Branch 1 taken 15 times.
2655 for(word j=0; j<176; j++)
2765 {
2766
2/2
✓ Branch 0 taken 26752 times.
✓ Branch 1 taken 2640 times.
29392 for(int32_t layer = -1; layer < 6; ++layer)
2767 {
2768 26752 mapscr* scr = screens[layer+1];
2769
2/2
✓ Branch 0 taken 16544 times.
✓ Branch 1 taken 10208 times.
26752 if (!scr) continue;
2770
2771
2/2
✓ Branch 0 taken 8272 times.
✓ Branch 1 taken 8272 times.
16544 if(sflag)
2772 8272 checkflag = scr->sflag[j];
2773 else
2774 8272 checkflag = combobuf[scr->data[j]].flag;
2775 16544 sflag = !sflag;
2776
2/2
✓ Branch 0 taken 8272 times.
✓ Branch 1 taken 8272 times.
16544 if (sflag) --layer;
2777
2778
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 16534 times.
16544 switch(checkflag)
2779 {
2780 case mfANYFIRE:
2781 case mfSTRONGFIRE:
2782 case mfMAGICFIRE:
2783 case mfDIVINEFIRE:
2784 case mfARROW:
2785 case mfSARROW:
2786 case mfGARROW:
2787 case mfSBOMB:
2788 case mfBOMB:
2789 case mfBRANG:
2790 case mfMBRANG:
2791 case mfFBRANG:
2792 case mfWANDMAGIC:
2793 case mfREFMAGIC:
2794 case mfREFFIREBALL:
2795 case mfSWORD:
2796 case mfWSWORD:
2797 case mfMSWORD:
2798 case mfXSWORD:
2799 case mfSWORDBEAM:
2800 case mfWSWORDBEAM:
2801 case mfMSWORDBEAM:
2802 case mfXSWORDBEAM:
2803 case mfHOOKSHOT:
2804 case mfWAND:
2805 case mfHAMMER:
2806 case mfSTRIKE:
2807 10 ret += 1;
2808 10 break;
2809 }
2810 16544 }
2811 2640 }
2812
2813 15 return ret;
2814 }
2815
2816 11738 static void log_trigger_secret_reason(TriggerSource source)
2817 {
2818
2/2
✓ Branch 0 taken 439 times.
✓ Branch 1 taken 11299 times.
11738 if (source == TriggerSource::Singular)
2819 {
2820 439 Z_eventlog("Restricted Screen Secrets triggered\n");
2821 439 }
2822 else
2823 {
2824 11299 const char* source_str = "";
2825
7/12
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 7178 times.
✓ Branch 3 taken 856 times.
✓ Branch 4 taken 2733 times.
✓ Branch 5 taken 475 times.
✓ Branch 6 taken 1 times.
✓ Branch 7 taken 52 times.
✓ Branch 8 taken 4 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
11299 switch (source)
2826 {
2827 case TriggerSource::Singular: break;
2828 7178 case TriggerSource::Unspecified: source_str = "unspecified means"; break;
2829 856 case TriggerSource::EnemiesScreenFlag: source_str = "the 'Enemies->Secret' screen flag"; break;
2830 2733 case TriggerSource::SecretsScreenState: source_str = "the 'Secrets' screen state"; break;
2831 475 case TriggerSource::Script: source_str = "a script"; break;
2832 1 case TriggerSource::ItemsSecret: source_str = "Items->Secrets"; break;
2833 52 case TriggerSource::GenericCombo: source_str = "Generic Combo"; break;
2834 4 case TriggerSource::LightTrigger: source_str = "Light Triggers"; break;
2835 case TriggerSource::SCC: source_str = "SCC"; break;
2836 case TriggerSource::CheatTemp: source_str = "Cheat (Temp)"; break;
2837 case TriggerSource::CheatPerm: source_str = "Cheat (Perm)"; break;
2838 }
2839 11299 Z_eventlog("Screen Secrets triggered by %s\n", source_str);
2840 }
2841 11738 }
2842
2843 // single:
2844 // >-1 : the singular triggering combo
2845 // -1: triggered by some other cause
2846 11530 void trigger_secrets_for_screen(TriggerSource source, mapscr* scr, bool high16only, int32_t single)
2847 {
2848 11530 log_trigger_secret_reason(source);
2849
2/2
✓ Branch 0 taken 439 times.
✓ Branch 1 taken 11091 times.
11530 if (single < 0)
2850 11091 get_screen_state(scr->screen).triggered_secrets = true;
2851
2852 11530 bool do_replay_comment = true;
2853 11530 bool from_active_screen = true;
2854 11530 trigger_secrets_for_screen_internal(create_screen_handles(scr), from_active_screen, high16only, single, do_replay_comment);
2855
2856 // Respect secret state carryovers for active screens.
2857
2/2
✓ Branch 0 taken 439 times.
✓ Branch 1 taken 11091 times.
11530 if (single >= 0) return;
2858
2/2
✓ Branch 0 taken 23 times.
✓ Branch 1 taken 11068 times.
11091 if(scr->nocarry&mSECRET) return;
2859 11068 int cmap = scr->map;
2860 11068 int cscr = scr->screen;
2861 11068 int nmap=TheMaps[((cmap)*MAPSCRS)+cscr].nextmap;
2862 11068 int nscr=TheMaps[((cmap)*MAPSCRS)+cscr].nextscr;
2863
2864 11068 std::vector<int32_t> done;
2865
2/2
✓ Branch 0 taken 10896 times.
✓ Branch 1 taken 172 times.
11068 bool looped = (nmap==cmap+1 && nscr==cscr);
2866
2867
6/6
✓ Branch 0 taken 484 times.
✓ Branch 1 taken 11001 times.
✓ Branch 2 taken 67 times.
✓ Branch 3 taken 417 times.
✓ Branch 4 taken 417 times.
✓ Branch 5 taken 11068 times.
11485 while((nmap!=0) && !looped && !(nscr>=128))
2868 {
2869
7/8
✓ Branch 0 taken 317 times.
✓ Branch 1 taken 100 times.
✓ Branch 2 taken 74 times.
✓ Branch 3 taken 243 times.
✓ Branch 4 taken 74 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 4 times.
✓ Branch 7 taken 70 times.
417 if (nmap - 1 == cur_map && is_in_current_region(nscr) && !get_screen_state(nscr).triggered_secrets)
2870 {
2871
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 log_trigger_secret_reason(TriggerSource::SecretsScreenState);
2872
3/6
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
4 trigger_secrets_for_screen_internal(create_screen_handles(get_scr(nscr)), from_active_screen, high16only, single, do_replay_comment);
2873
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 get_screen_state(nscr).triggered_secrets = true;
2874 4 }
2875
2876 417 cmap=nmap;
2877 417 cscr=nscr;
2878 417 nmap=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextmap;
2879 417 nscr=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextscr;
2880
2881
2/2
✓ Branch 0 taken 386 times.
✓ Branch 1 taken 417 times.
803 for(auto it = done.begin(); it != done.end(); it++)
2882 {
2883
2/2
✓ Branch 0 taken 319 times.
✓ Branch 1 taken 67 times.
386 if(*it == ((nmap-1)<<7)+nscr)
2884 67 looped = true;
2885 386 }
2886
2887
1/2
✓ Branch 0 taken 417 times.
✗ Branch 1 not taken.
417 done.push_back(((nmap-1)<<7)+nscr);
2888 }
2889 11530 }
2890
2891 2437 void trigger_secrets_for_screen(TriggerSource source, int32_t screen, bool high16only, int32_t single)
2892 {
2893 2437 trigger_secrets_for_screen(source, get_scr(screen), high16only, single);
2894 2437 }
2895
2896 18007 void trigger_secrets_for_screen_internal(const screen_handles_t& screen_handles, bool from_active_screen, bool high16only, int32_t single, bool do_replay_comment)
2897 {
2898 18007 mapscr* scr = screen_handles[0].scr;
2899 18007 int screen = scr->screen;
2900
2901 // TODO(replays): No real reason for "do_replay_comment" to exist - I just did not want to update many replays when fixing
2902 // slopes in sideview mode (which required loading nearby screens in loadscr).
2903 // TODO(replays): This should just use `screen`.
2904
3/4
✓ Branch 0 taken 18007 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 539 times.
✓ Branch 3 taken 17468 times.
18007 if (replay_is_active() && do_replay_comment)
2905
4/6
✓ Branch 0 taken 11534 times.
✓ Branch 1 taken 5934 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 11534 times.
✓ Branch 4 taken 17468 times.
✗ Branch 5 not taken.
17468 replay_step_comment(fmt::format("trigger secrets scr={}", from_active_screen && scr != special_warp_return_scr ? screen : cur_screen));
2906
2907
2/2
✓ Branch 0 taken 6473 times.
✓ Branch 1 taken 11534 times.
18007 if (from_active_screen)
2908 {
2909 5442998 for_every_combo_in_screen(screen_handles, [&](const auto& handle) {
2910
2/4
✓ Branch 0 taken 5429776 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1688 times.
✗ Branch 3 not taken.
5661701 trig_each_combo_trigger(handle, [&](combo_trigger const& trig){
2911 230237 return trig.trigger_flags.get(TRIGFLAG_SECRETSTR);
2912 }, ctrigSECRETS);
2913 5431464 });
2914 11534 }
2915
2916 18007 int32_t ft=0; //Flag trigger?
2917 18007 int32_t msflag=0; // Misc. secret flag
2918
2919
2/2
✓ Branch 0 taken 3169232 times.
✓ Branch 1 taken 18007 times.
3187239 for(int32_t i=0; i<176; i++) //Do the 'trigger flags' (non 16-31)
2920 {
2921
4/4
✓ Branch 0 taken 77264 times.
✓ Branch 1 taken 3091968 times.
✓ Branch 2 taken 439 times.
✓ Branch 3 taken 76825 times.
3169232 if(single>=0 && i!=single) continue; //If it's got a singular flag and i isn't where the flag is
2922
2923 // Remember the misc. secret flag; if triggered, use this instead
2924
4/4
✓ Branch 0 taken 114511 times.
✓ Branch 1 taken 2977896 times.
✓ Branch 2 taken 49462 times.
✓ Branch 3 taken 65049 times.
3092407 if(scr->sflag[i]>=mfSECRETS01 && scr->sflag[i]<=mfSECRETS16)
2925 65049 msflag=sSECRET01+(scr->sflag[i]-mfSECRETS01);
2926
4/4
✓ Branch 0 taken 47230 times.
✓ Branch 1 taken 2980128 times.
✓ Branch 2 taken 46999 times.
✓ Branch 3 taken 231 times.
3027358 else if(combobuf[scr->data[i]].flag>=mfSECRETS01 && combobuf[scr->data[i]].flag<=mfSECRETS16)
2927 231 msflag=sSECRET01+(combobuf[scr->data[i]].flag-mfSECRETS01);
2928 else
2929 3027127 msflag=0;
2930
2931
4/4
✓ Branch 0 taken 921256 times.
✓ Branch 1 taken 2171151 times.
✓ Branch 2 taken 72 times.
✓ Branch 3 taken 921184 times.
3092407 if(!high16only || single>=0)
2932 {
2933 2171223 int32_t newflag = -1;
2934
2935
2/2
✓ Branch 0 taken 4342446 times.
✓ Branch 1 taken 2171223 times.
6513669 for(int32_t iter=0; iter<2; ++iter)
2936 {
2937 4342446 int32_t checkflag=combobuf[scr->data[i]].flag; //Inherent
2938
2939
2/2
✓ Branch 0 taken 2171223 times.
✓ Branch 1 taken 2171223 times.
4342446 if(iter==1) checkflag=scr->sflag[i]; //Placed
2940
2941 4342446 ft = combo_trigger_flag_to_secret_combo_index(checkflag);
2942
2/2
✓ Branch 0 taken 4330212 times.
✓ Branch 1 taken 12234 times.
4342446 if (ft != -1) //Change the combos for the secret
2943 {
2944 // Use misc. secret flag instead if one is present
2945
2/2
✓ Branch 0 taken 12202 times.
✓ Branch 1 taken 32 times.
12234 if(msflag!=0)
2946 32 ft=msflag;
2947
2948 12234 rpos_handle_t rpos_handle;
2949
2/2
✓ Branch 0 taken 6367 times.
✓ Branch 1 taken 5867 times.
12234 if (from_active_screen)
2950 {
2951 5867 rpos_handle = get_rpos_handle_for_scr(scr, 0, i);
2952 5867 screen_combo_modify_preroutine(rpos_handle);
2953 5867 }
2954
2955
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12234 times.
12234 if(ft==sSECNEXT)
2956 {
2957 scr->data[i]++;
2958 }
2959 else
2960 {
2961 12234 scr->data[i] = scr->secretcombo[ft];
2962 12234 scr->cset[i] = scr->secretcset[ft];
2963 }
2964 12234 newflag = scr->secretflag[ft];
2965
2966
2/2
✓ Branch 0 taken 6367 times.
✓ Branch 1 taken 5867 times.
12234 if (from_active_screen)
2967 5867 screen_combo_modify_postroutine(rpos_handle);
2968 12234 }
2969 4342446 }
2970
2971
2/2
✓ Branch 0 taken 2158995 times.
✓ Branch 1 taken 12228 times.
2171223 if(newflag >-1) scr->sflag[i] = newflag; //Tiered secret
2972
2973
2/2
✓ Branch 0 taken 13027338 times.
✓ Branch 1 taken 2171223 times.
15198561 for(int32_t j=1; j<=6; j++) //Layers
2974 {
2975 13027338 mapscr* layer_scr = screen_handles[j].scr;
2976
2/2
✓ Branch 0 taken 3185797 times.
✓ Branch 1 taken 9841541 times.
13027338 if (!layer_scr) continue;
2977
2978
3/4
✓ Branch 0 taken 725 times.
✓ Branch 1 taken 3185072 times.
✓ Branch 2 taken 725 times.
✗ Branch 3 not taken.
3185797 if(single>=0 && i!=single) continue; //If it's got a singular flag and i isn't where the flag is
2979
2980 3185797 int32_t newflag2 = -1;
2981
2982 // Remember the misc. secret flag; if triggered, use this instead
2983
4/4
✓ Branch 0 taken 14182 times.
✓ Branch 1 taken 3171615 times.
✓ Branch 2 taken 4773 times.
✓ Branch 3 taken 9409 times.
3185797 if(layer_scr->sflag[i]>=mfSECRETS01 && layer_scr->sflag[i]<=mfSECRETS16)
2984 9409 msflag=sSECRET01+(layer_scr->sflag[i]-mfSECRETS01);
2985
4/4
✓ Branch 0 taken 126931 times.
✓ Branch 1 taken 3049457 times.
✓ Branch 2 taken 126560 times.
✓ Branch 3 taken 371 times.
3176388 else if(combobuf[layer_scr->data[i]].flag>=mfSECRETS01 && combobuf[layer_scr->data[i]].flag<=mfSECRETS16)
2986 371 msflag=sSECRET01+(combobuf[layer_scr->data[i]].flag-mfSECRETS01);
2987 else
2988 3176017 msflag=0;
2989
2990
2/2
✓ Branch 0 taken 6371594 times.
✓ Branch 1 taken 3185797 times.
9557391 for(int32_t iter=0; iter<2; ++iter)
2991 {
2992 6371594 int32_t checkflag=combobuf[layer_scr->data[i]].flag; //Inherent
2993
2/2
✓ Branch 0 taken 3185797 times.
✓ Branch 1 taken 3185797 times.
6371594 if(iter==1) checkflag=layer_scr->sflag[i]; //Placed
2994
2995 6371594 ft = combo_trigger_flag_to_secret_combo_index(checkflag);
2996
2/2
✓ Branch 0 taken 6371116 times.
✓ Branch 1 taken 478 times.
6371594 if (ft != -1) //Change the combos for the secret
2997 {
2998 // Use misc. secret flag instead if one is present
2999
2/2
✓ Branch 0 taken 476 times.
✓ Branch 1 taken 2 times.
478 if(msflag!=0)
3000 2 ft=msflag;
3001
3002
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 478 times.
478 if(ft==sSECNEXT)
3003 {
3004 layer_scr->data[i]++;
3005 }
3006 else
3007 {
3008 478 layer_scr->data[i] = layer_scr->secretcombo[ft];
3009 478 layer_scr->cset[i] = layer_scr->secretcset[ft];
3010 }
3011 478 newflag2 = layer_scr->secretflag[ft];
3012 478 int32_t c=layer_scr->data[i];
3013 478 int32_t cs=layer_scr->cset[i];
3014
3015
3/4
✓ Branch 0 taken 406 times.
✓ Branch 1 taken 72 times.
✓ Branch 2 taken 406 times.
✗ Branch 3 not taken.
478 if (from_active_screen && combobuf[c].type==cSPINTILE1) //Surely this means we can have spin tiles on layers 3+? Isn't that bad? ~Joe123
3016 {
3017 auto [offx, offy] = translate_screen_coordinates_to_world(screen, COMBOX(i), COMBOY(i));
3018 addenemy(screen,offx,offy,(cs<<12)+eSPINTILE1,combobuf[c].o_tile+zc_max(1,combobuf[c].frames));
3019 }
3020 478 }
3021 6371594 }
3022
3023
2/2
✓ Branch 0 taken 478 times.
✓ Branch 1 taken 3185319 times.
3185797 if(newflag2 >-1) layer_scr->sflag[i] = newflag2; //Tiered secret
3024 3185797 }
3025 2171223 }
3026 3092407 }
3027
3028 18007 word c = scr->numFFC();
3029
2/2
✓ Branch 0 taken 506903 times.
✓ Branch 1 taken 18007 times.
524910 for(word i=0; i<c; i++) //FFC 'trigger flags'
3030 {
3031
3/4
✓ Branch 0 taken 492983 times.
✓ Branch 1 taken 13920 times.
✓ Branch 2 taken 13920 times.
✗ Branch 3 not taken.
506903 if(single>=0) if(i+176!=single) continue;
3032
3033
3/4
✓ Branch 0 taken 166605 times.
✓ Branch 1 taken 326378 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 166605 times.
492983 if((!high16only)||(single>=0))
3034 {
3035 //for (int32_t iter=0; iter<1; ++iter) // Only one kind of FFC flag now.
3036 {
3037 326378 int32_t checkflag=combobuf[scr->ffcs[i].data].flag; //Inherent
3038 //No placed flags yet
3039
3040 326378 ft = combo_trigger_flag_to_secret_combo_index(checkflag);
3041
2/2
✓ Branch 0 taken 326347 times.
✓ Branch 1 taken 31 times.
326378 if (ft != -1) //Change the ffc's combo
3042 {
3043
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 31 times.
31 if(ft==sSECNEXT)
3044 {
3045 zc_ffc_modify(scr->ffcs[i], 1);
3046 }
3047 else
3048 {
3049 31 zc_ffc_set(scr->ffcs[i], scr->secretcombo[ft]);
3050 31 scr->ffcs[i].cset = scr->secretcset[ft];
3051 }
3052 31 }
3053 }
3054 326378 }
3055 492983 }
3056
3057
2/2
✓ Branch 0 taken 15610 times.
✓ Branch 1 taken 2397 times.
18007 if(checktrigger) //Hit all triggers->16-31
3058 {
3059 2397 checktrigger=false;
3060
3061
2/2
✓ Branch 0 taken 2388 times.
✓ Branch 1 taken 9 times.
2397 if(scr->flags6&fTRIGGERF1631)
3062 {
3063 9 int32_t tr = findtrigger(screen); //Normal flags
3064
3065
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 4 times.
9 if(tr)
3066 {
3067 5 Z_eventlog("Hit All Triggers->16-31 not fulfilled (%d trigger flag%s remain).\n", tr, tr>1?"s":"");
3068 5 goto endhe;
3069 }
3070 4 }
3071 2392 }
3072
3073
2/2
✓ Branch 0 taken 3168352 times.
✓ Branch 1 taken 18002 times.
3186354 for(int32_t i=0; i<176; i++) // Do the 16-31 secrets
3074 {
3075 //If it's an enemies->secret screen, only do the high 16 if told to
3076 //That way you can have secret and burn/bomb entrance separately
3077 3168352 bool old_enem_secret = get_qr(qr_ENEMIES_SECRET_ONLY_16_31);
3078
6/6
✓ Branch 0 taken 2780624 times.
✓ Branch 1 taken 387728 times.
✓ Branch 2 taken 85184 times.
✓ Branch 3 taken 3083168 times.
✓ Branch 4 taken 19536 times.
✓ Branch 5 taken 65648 times.
3168352 if(((!(old_enem_secret && (scr->flags2&fCLEARSECRET)) /*Enemies->Secret*/ && single < 0) || high16only || scr->flags4&fENEMYSCRTPERM))
3079 {
3080 3102704 int32_t newflag = -1;
3081
3082
2/2
✓ Branch 0 taken 6205408 times.
✓ Branch 1 taken 3102704 times.
9308112 for(int32_t iter=0; iter<2; ++iter)
3083 {
3084 6205408 int32_t checkflag=combobuf[scr->data[i]].flag; //Inherent
3085
3086
2/2
✓ Branch 0 taken 3102704 times.
✓ Branch 1 taken 3102704 times.
6205408 if(iter==1) checkflag=scr->sflag[i]; //Placed
3087
3088
4/4
✓ Branch 0 taken 161185 times.
✓ Branch 1 taken 6044223 times.
✓ Branch 2 taken 94853 times.
✓ Branch 3 taken 66332 times.
6205408 if((checkflag > 15)&&(checkflag < 32)) //If we've got a 16->32 flag change the combo
3089 {
3090 66332 rpos_handle_t rpos_handle;
3091
2/2
✓ Branch 0 taken 9952 times.
✓ Branch 1 taken 56380 times.
66332 if (from_active_screen)
3092 {
3093 56380 rpos_handle = get_rpos_handle_for_scr(scr, 0, i);
3094 56380 screen_combo_modify_preroutine(rpos_handle);
3095 56380 }
3096
3097 66332 scr->data[i] = scr->secretcombo[checkflag-16+4];
3098 66332 scr->cset[i] = scr->secretcset[checkflag-16+4];
3099 66332 newflag = scr->secretflag[checkflag-16+4];
3100
3101
2/2
✓ Branch 0 taken 9952 times.
✓ Branch 1 taken 56380 times.
66332 if (from_active_screen)
3102 56380 screen_combo_modify_postroutine(rpos_handle);
3103 66332 }
3104 6205408 }
3105
3106
2/2
✓ Branch 0 taken 3036396 times.
✓ Branch 1 taken 66308 times.
3102704 if(newflag >-1) scr->sflag[i] = newflag; //Tiered flag
3107
3108
2/2
✓ Branch 0 taken 18616224 times.
✓ Branch 1 taken 3102704 times.
21718928 for(int32_t j=1; j<=6; j++) //Layers
3109 {
3110 18616224 mapscr* layer_scr = screen_handles[j].scr;
3111
2/2
✓ Branch 0 taken 4866752 times.
✓ Branch 1 taken 13749472 times.
18616224 if (!layer_scr) continue;
3112
3113 4866752 int32_t newflag2 = -1;
3114
3115
2/2
✓ Branch 0 taken 9733504 times.
✓ Branch 1 taken 4866752 times.
14600256 for(int32_t iter=0; iter<2; ++iter)
3116 {
3117 9733504 int32_t checkflag=combobuf[layer_scr->data[i]].flag; //Inherent
3118
3119
2/2
✓ Branch 0 taken 4866752 times.
✓ Branch 1 taken 4866752 times.
9733504 if(iter==1) checkflag=layer_scr->sflag[i]; //Placed
3120
3121
4/4
✓ Branch 0 taken 151246 times.
✓ Branch 1 taken 9582258 times.
✓ Branch 2 taken 131622 times.
✓ Branch 3 taken 19624 times.
9733504 if((checkflag > 15)&&(checkflag < 32)) //If we've got a 16->32 flag change the combo
3122 {
3123 19624 layer_scr->data[i] = layer_scr->secretcombo[checkflag-16+4];
3124 19624 layer_scr->cset[i] = layer_scr->secretcset[checkflag-16+4];
3125 19624 newflag2 = layer_scr->secretflag[checkflag-16+4];
3126 19624 }
3127 9733504 }
3128
3129
2/2
✓ Branch 0 taken 4847128 times.
✓ Branch 1 taken 19624 times.
4866752 if(newflag2 >-1) layer_scr->sflag[i] = newflag2; //Tiered flag
3130 4866752 }
3131 3102704 }
3132 3168352 }
3133
3134
2/2
✓ Branch 0 taken 506743 times.
✓ Branch 1 taken 18002 times.
524745 for(word i=0; i<c; i++) // FFCs
3135 {
3136
6/6
✓ Branch 0 taken 466852 times.
✓ Branch 1 taken 39891 times.
✓ Branch 2 taken 15367 times.
✓ Branch 3 taken 491376 times.
✓ Branch 4 taken 3530 times.
✓ Branch 5 taken 11837 times.
506743 if((!(scr->flags2&fCLEARSECRET) /*Enemies->Secret*/ && single < 0) || high16only || scr->flags4&fENEMYSCRTPERM)
3137 {
3138 494906 int32_t checkflag=combobuf[scr->ffcs[i].data].flag; //Inherent
3139
3140 //No placed flags yet
3141
4/4
✓ Branch 0 taken 68 times.
✓ Branch 1 taken 494838 times.
✓ Branch 2 taken 56 times.
✓ Branch 3 taken 12 times.
494906 if((checkflag > 15)&&(checkflag < 32)) //If we find a flag, change the combo
3142 {
3143
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 3 times.
12 if (from_active_screen)
3144 9 zc_ffc_set(scr->ffcs[i], scr->secretcombo[checkflag - 16 + 4]);
3145 else
3146 3 scr->ffcs[i].data = scr->secretcombo[checkflag - 16 + 4];
3147 12 scr->ffcs[i].cset = scr->secretcset[checkflag-16+4];
3148 12 }
3149 494906 }
3150 524745 }
3151
3152 endhe:
3153
3154
1/2
✓ Branch 0 taken 18007 times.
✗ Branch 1 not taken.
18007 if (scr->flags4&fDISABLETIME) //Finish timed warp if 'Secrets Disable Timed Warp'
3155 {
3156 if (from_active_screen)
3157 activated_timed_warp = true;
3158 scr->timedwarptics = 0;
3159 }
3160 18007 }
3161
3162 // x,y are world coordinates.
3163 // Returns true if there is a flag (either combo, screen, or ffc) at (x, y).
3164 // Out parameters will be set if the flag is Trigger->Self, which modifies how secrets will be triggered.
3165 13508239 static bool has_flag_trigger(int32_t x, int32_t y, int32_t flag, rpos_t& out_rpos, bool& out_single16)
3166 {
3167
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13508239 times.
13508239 if (!is_in_world_bounds(x, y)) return false;
3168
3169 13508239 bool found_cflag = false;
3170 13508239 bool found_nflag = false;
3171 13508239 bool single16 = false;
3172 13508239 rpos_t rpos = rpos_t::None;
3173
3174
2/2
✓ Branch 0 taken 13506155 times.
✓ Branch 1 taken 94545481 times.
108051636 for (int32_t layer = -1; layer < 6; layer++)
3175 {
3176
2/2
✓ Branch 0 taken 94543397 times.
✓ Branch 1 taken 2084 times.
94545481 if (MAPFLAG2(layer, x, y) == flag)
3177 {
3178 2084 found_nflag = true;
3179 2084 break;
3180 }
3181 94543397 }
3182
3183
2/2
✓ Branch 0 taken 13507935 times.
✓ Branch 1 taken 94556397 times.
108064332 for (int32_t layer = -1; layer < 6; layer++)
3184 {
3185
2/2
✓ Branch 0 taken 94556093 times.
✓ Branch 1 taken 304 times.
94556397 if (MAPCOMBOFLAG2(layer, x, y) == flag)
3186 {
3187 304 found_cflag = true;
3188 304 break;
3189 }
3190 94556093 }
3191
3192
2/2
✓ Branch 0 taken 94557673 times.
✓ Branch 1 taken 13508239 times.
108065912 for (int32_t i=-1; i<6; i++) // Look for Trigger->Self on all layers
3193 {
3194
2/2
✓ Branch 0 taken 94543085 times.
✓ Branch 1 taken 14588 times.
94557673 if (found_nflag) // Trigger->Self (a.k.a Singular) is inherent
3195 {
3196
3/4
✓ Branch 0 taken 112 times.
✓ Branch 1 taken 14476 times.
✓ Branch 2 taken 112 times.
✗ Branch 3 not taken.
14588 if ((MAPCOMBOFLAG2(i, x, y) == mfSINGLE) && (MAPFLAG2(i, x, y) == flag))
3197 {
3198 112 rpos = COMBOPOS_REGION(x, y);
3199 112 }
3200
3/4
✓ Branch 0 taken 52 times.
✓ Branch 1 taken 14424 times.
✓ Branch 2 taken 52 times.
✗ Branch 3 not taken.
14476 else if ((MAPCOMBOFLAG2(i, x, y) == mfSINGLE16) && (MAPFLAG2(i, x, y) == flag))
3201 {
3202 52 rpos = COMBOPOS_REGION(x, y);
3203 52 single16 = true;
3204 52 }
3205 14588 }
3206
3207
2/2
✓ Branch 0 taken 94555545 times.
✓ Branch 1 taken 2128 times.
94557673 if (found_cflag) // Trigger->Self (a.k.a Singular) is non-inherent
3208 {
3209
3/4
✓ Branch 0 taken 255 times.
✓ Branch 1 taken 1873 times.
✓ Branch 2 taken 255 times.
✗ Branch 3 not taken.
2128 if ((MAPFLAG2(i, x, y) == mfSINGLE) && (MAPCOMBOFLAG2(i, x, y) == flag))
3210 {
3211 255 rpos = COMBOPOS_REGION(x, y);
3212 255 }
3213
3/4
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 1853 times.
✓ Branch 2 taken 20 times.
✗ Branch 3 not taken.
1873 else if ((MAPFLAG2(i, x, y) == mfSINGLE16) && (MAPCOMBOFLAG2(i, x, y) == flag))
3214 {
3215 20 rpos = COMBOPOS_REGION(x, y);
3216 20 single16 = true;
3217 20 }
3218 2128 }
3219 94557673 }
3220
3221 13508239 out_rpos = rpos;
3222 13508239 out_single16 = single16;
3223
4/4
✓ Branch 0 taken 13506155 times.
✓ Branch 1 taken 2084 times.
✓ Branch 2 taken 13505853 times.
✓ Branch 3 taken 302 times.
13508239 return found_nflag || found_cflag || MAPFFCOMBOFLAG(x,y) == flag;
3224 13508239 }
3225
3226 4457867 bool trigger_secrets_if_flag(int32_t x, int32_t y, int32_t flag, bool setflag)
3227 {
3228
8/8
✓ Branch 0 taken 4457627 times.
✓ Branch 1 taken 240 times.
✓ Branch 2 taken 4455730 times.
✓ Branch 3 taken 1897 times.
✓ Branch 4 taken 4455210 times.
✓ Branch 5 taken 520 times.
✓ Branch 6 taken 952 times.
✓ Branch 7 taken 4454258 times.
4457867 if (x < -16 || y < -16 || x >= world_w || y >= world_h) return false;
3229
3230 4454258 mapscr* scr = NULL;
3231 4454258 int32_t screen = -1;
3232 4454258 rpos_t trigger_rpos = rpos_t::None;
3233 4454258 bool single16 = false;
3234
3235 4454258 std::vector<std::pair<int, int>> coords;
3236
1/2
✓ Branch 0 taken 4454258 times.
✗ Branch 1 not taken.
4454258 coords.push_back({x, y});
3237
1/2
✓ Branch 0 taken 4454258 times.
✗ Branch 1 not taken.
4454258 coords.push_back({x + 15, y});
3238
1/2
✓ Branch 0 taken 4454258 times.
✗ Branch 1 not taken.
4454258 coords.push_back({x, y + 15});
3239
1/2
✓ Branch 0 taken 4454258 times.
✗ Branch 1 not taken.
4454258 coords.push_back({x + 15, y + 15});
3240 4454258 std::vector<rpos_t> rposes_seen;
3241
2/2
✓ Branch 0 taken 4451861 times.
✓ Branch 1 taken 17811750 times.
84483617 for (auto [x, y] : coords)
3242 {
3243
2/4
✓ Branch 0 taken 17811750 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 17811750 times.
✗ Branch 3 not taken.
35623500 rpos_t rpos = COMBOPOS_REGION_B(x, y);
3244
2/2
✓ Branch 0 taken 17599367 times.
✓ Branch 1 taken 212383 times.
17811750 if (rpos == rpos_t::None)
3245 212383 continue;
3246
3247
4/6
✓ Branch 0 taken 17599367 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 17599367 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 11 times.
✓ Branch 5 taken 17599356 times.
35198734 if (MAPFFCOMBOFLAG(x, y) == flag)
3248 {
3249
2/4
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11 times.
✗ Branch 3 not taken.
22 screen = get_screen_for_world_xy(x, y);
3250 11 break;
3251 }
3252
3253 17599356 bool seen = false;
3254
2/2
✓ Branch 0 taken 13508239 times.
✓ Branch 1 taken 22128287 times.
35636526 for (rpos_t r : rposes_seen)
3255 {
3256
2/2
✓ Branch 0 taken 18037170 times.
✓ Branch 1 taken 4091117 times.
22128287 if (r == rpos)
3257 {
3258 4091117 seen = true;
3259 4091117 break;
3260 }
3261 }
3262
2/2
✓ Branch 0 taken 13508239 times.
✓ Branch 1 taken 4091117 times.
17599356 if (seen)
3263 4091117 continue;
3264
3265
1/2
✓ Branch 0 taken 13508239 times.
✗ Branch 1 not taken.
13508239 rposes_seen.push_back(rpos);
3266
4/6
✓ Branch 0 taken 13508239 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 13508239 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2386 times.
✓ Branch 5 taken 13505853 times.
27016478 if (has_flag_trigger(x, y, flag, trigger_rpos, single16))
3267 {
3268
2/4
✓ Branch 0 taken 2386 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2386 times.
✗ Branch 3 not taken.
4772 screen = get_screen_for_world_xy(x, y);
3269 2386 break;
3270 }
3271 }
3272
3273
3/4
✓ Branch 0 taken 2397 times.
✓ Branch 1 taken 4451861 times.
✓ Branch 2 taken 2397 times.
✗ Branch 3 not taken.
4454258 if (screen != -1) scr = get_scr(screen);
3274
2/2
✓ Branch 0 taken 2397 times.
✓ Branch 1 taken 4451861 times.
4454258 if (!scr) return false;
3275
3276
2/2
✓ Branch 0 taken 1958 times.
✓ Branch 1 taken 439 times.
2397 if (trigger_rpos == rpos_t::None)
3277 {
3278 1958 checktrigger = true;
3279
1/2
✓ Branch 0 taken 1958 times.
✗ Branch 1 not taken.
1958 trigger_secrets_for_screen(TriggerSource::Unspecified, screen);
3280 1958 }
3281 else
3282 {
3283 439 checktrigger = true;
3284
2/4
✓ Branch 0 taken 439 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 439 times.
✗ Branch 3 not taken.
439 trigger_secrets_for_screen(TriggerSource::Singular, scr, single16, RPOS_TO_POS(trigger_rpos));
3285 }
3286
3287
1/2
✓ Branch 0 taken 2397 times.
✗ Branch 1 not taken.
2397 sfx(scr->secretsfx);
3288
3289
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 2391 times.
2397 if(scr->flags6&fTRIGGERFPERM)
3290 {
3291
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 int32_t flags_remaining = findtrigger(screen); //Normal flags
3292
3293
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
6 if (flags_remaining)
3294 {
3295
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 Z_eventlog("Hit All Triggers->Perm Secret not fulfilled (%d trigger flag%s remain).\n", flags_remaining, flags_remaining>1?"s":"");
3296 3 setflag=false;
3297 3 }
3298
3299 // Only actually trigger secrets now if 1) all triggers are gone and 2) QR qr_ALLTRIG_PERMSEC_NO_TEMP is off, in
3300 // which case only the screen state for mSECRET may be set below.
3301
3/4
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
6 if (!flags_remaining && !get_qr(qr_ALLTRIG_PERMSEC_NO_TEMP))
3302 {
3303 trigger_secrets_for_screen(TriggerSource::Unspecified, scr, scr->flags6&fTRIGGERF1631, -1);
3304 }
3305 6 }
3306
3307
5/6
✓ Branch 0 taken 2292 times.
✓ Branch 1 taken 105 times.
✓ Branch 2 taken 2292 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1108 times.
✓ Branch 5 taken 1184 times.
2397 if (setflag && canPermSecret(cur_dmap, screen))
3308
2/2
✓ Branch 0 taken 721 times.
✓ Branch 1 taken 463 times.
1905 if(!(scr->flags5&fTEMPSECRETS))
3309
1/2
✓ Branch 0 taken 721 times.
✗ Branch 1 not taken.
721 setmapflag(scr, mSECRET);
3310
3311 2397 return true;
3312 4457867 }
3313
3314 14809012 void update_slopes()
3315 {
3316
2/2
✓ Branch 0 taken 142356 times.
✓ Branch 1 taken 14809012 times.
14951368 for (auto& p : slopes)
3317 {
3318 142356 slope_object& s = p.second;
3319 142356 s.updateslope(); //sets old x/y poses
3320 }
3321 14809012 }
3322
3323 14402369 void update_freeform_combos()
3324 {
3325 14402369 ffscript_engine(false);
3326
2/2
✓ Branch 0 taken 24172 times.
✓ Branch 1 taken 14378197 times.
14402369 if ( !FFCore.system_suspend[susptUPDATEFFC] )
3327 {
3328 14378197 int wrap_right = world_w + 32;
3329 14378197 int wrap_bottom = world_h + 32;
3330
3331 485520731 for_every_ffc([&](const ffc_handle_t& ffc_handle) {
3332 471142534 mapscr* scr = ffc_handle.scr;
3333 471142534 ffcdata& thisffc = *ffc_handle.ffc;
3334
3335 // Combo 0?
3336
2/2
✓ Branch 0 taken 44992239 times.
✓ Branch 1 taken 426150295 times.
471142534 if(thisffc.data==0)
3337 426150295 return;
3338
3339 // Changer?
3340
2/2
✓ Branch 0 taken 543029 times.
✓ Branch 1 taken 44449210 times.
44992239 if(thisffc.flags&ffc_changer)
3341 543029 return;
3342
3343 // Stationary?
3344
2/2
✓ Branch 0 taken 9844 times.
✓ Branch 1 taken 44439366 times.
44449210 if(thisffc.flags&ffc_stationary)
3345 9844 return;
3346
3347 // Frozen because Hero's holding up an item?
3348
3/4
✓ Branch 0 taken 138282 times.
✓ Branch 1 taken 44301084 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 138282 times.
44439366 if(Hero.getHoldClk()>0 && (thisffc.flags&ffc_ignoreholdup)==0)
3349 138282 return;
3350
3351 // Check for changers
3352
2/2
✓ Branch 0 taken 29543786 times.
✓ Branch 1 taken 14757298 times.
44301084 if (thisffc.link==0)
3353 {
3354 442453159 for_some_ffcs([&](const ffc_handle_t& other_ffc_handle) {
3355
2/2
✓ Branch 0 taken 14755762 times.
✓ Branch 1 taken 412940099 times.
427695861 if (ffc_handle.id == other_ffc_handle.id)
3356 14755762 return true;
3357
3358 412940099 ffcdata& otherffc = *other_ffc_handle.ffc;
3359 // Combo 0?
3360
2/2
✓ Branch 0 taken 144689583 times.
✓ Branch 1 taken 268250516 times.
412940099 if(otherffc.data==0)
3361 268250516 return true;
3362
3363 // Not a changer?
3364
2/2
✓ Branch 0 taken 140701406 times.
✓ Branch 1 taken 3988177 times.
144689583 if(!(otherffc.flags&ffc_changer))
3365 140701406 return true;
3366
3367 // Ignore this changer?
3368
4/4
✓ Branch 0 taken 546579 times.
✓ Branch 1 taken 3441598 times.
✓ Branch 2 taken 299257 times.
✓ Branch 3 taken 3142341 times.
3988177 if((otherffc.x.getInt()==thisffc.changer_x&&otherffc.y.getInt()==thisffc.changer_y) || thisffc.flags&ffc_ignorechanger)
3369 845836 return true;
3370
3371
3/4
✓ Branch 0 taken 2721043 times.
✓ Branch 1 taken 421298 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3562 times.
3145903 if((isonline(thisffc.x.getZLong(), thisffc.y.getZLong(), thisffc.prev_changer_x, thisffc.prev_changer_y, otherffc.x.getZLong(), otherffc.y.getZLong()) || // Along the line, or...
3372 ( // At exactly the same position,
3373
2/2
✓ Branch 0 taken 208792 times.
✓ Branch 1 taken 2512251 times.
2721043 (thisffc.x==otherffc.x && thisffc.y==otherffc.y))
3374
2/2
✓ Branch 0 taken 2303459 times.
✓ Branch 1 taken 2512251 times.
208792 ||
3375 //or imprecision and close enough
3376
0/2
✗ Branch 0 not taken.
✗ Branch 1 not taken.
5024502 ( (thisffc.flags&ffc_imprecisionchanger) && ((abs(thisffc.x.getZLong() - otherffc.x.getZLong()) < 10000) && abs(thisffc.y.getZLong() - otherffc.y.getZLong()) < 10000) )
3377 )
3378 && //and...
3379
2/2
✓ Branch 0 taken 3562 times.
✓ Branch 1 taken 2721195 times.
2724757 (thisffc.prev_changer_x>-10000000 && thisffc.prev_changer_y>-10000000)) // This isn't the first frame on this screen
3380 {
3381 3562 zc_ffc_changer(thisffc, otherffc, ffc_handle.id, other_ffc_handle.id);
3382 3562 return false;
3383 }
3384
3385 2721195 return true;
3386 426679763 });
3387 14757298 }
3388
3389
2/2
✓ Branch 0 taken 29543786 times.
✓ Branch 1 taken 14757298 times.
44301084 ffcdata* linked_ffc = thisffc.link ? get_ffc_handle(thisffc.link - 1).ffc : nullptr;
3390
4/4
✓ Branch 0 taken 14757298 times.
✓ Branch 1 taken 29543786 times.
✓ Branch 2 taken 14680008 times.
✓ Branch 3 taken 14863778 times.
44301084 if (linked_ffc ? !linked_ffc->delay : !thisffc.delay)
3391 {
3392
4/4
✓ Branch 0 taken 182609 times.
✓ Branch 1 taken 14681169 times.
✓ Branch 2 taken 85331 times.
✓ Branch 3 taken 97278 times.
14863778 if(thisffc.link && (thisffc.link-1) != ffc_handle.id)
3393 {
3394 97278 thisffc.prev_changer_x = thisffc.x.getZLong();
3395 97278 thisffc.prev_changer_y = thisffc.y.getZLong();
3396 97278 thisffc.x += linked_ffc->vx;
3397 97278 thisffc.y += linked_ffc->vy;
3398 97278 }
3399 else
3400 {
3401 14766500 thisffc.prev_changer_x = thisffc.x.getZLong();
3402 14766500 thisffc.prev_changer_y = thisffc.y.getZLong();
3403 14766500 thisffc.x += thisffc.vx;
3404 14766500 thisffc.y += thisffc.vy;
3405 14766500 thisffc.vx += thisffc.ax;
3406 14766500 thisffc.vy += thisffc.ay;
3407
3408
3409
2/2
✓ Branch 0 taken 444046 times.
✓ Branch 1 taken 14322454 times.
14766500 if(get_qr(qr_OLD_FFC_SPEED_CAP))
3410 {
3411
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14322454 times.
14322454 if(thisffc.vx>128) thisffc.vx=128;
3412
3413
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14322454 times.
14322454 if(thisffc.vx<-128) thisffc.vx=-128;
3414
3415
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14322454 times.
14322454 if(thisffc.vy>128) thisffc.vy=128;
3416
3417
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14322454 times.
14322454 if(thisffc.vy<-128) thisffc.vy=-128;
3418 14322454 }
3419 }
3420 14863778 }
3421 else
3422 {
3423
3/4
✓ Branch 0 taken 1161 times.
✓ Branch 1 taken 76129 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1161 times.
29437306 if(!thisffc.link || (thisffc.link-1) == ffc_handle.id)
3424 76129 thisffc.delay--;
3425 }
3426
3427 // Check if the FFC's off the side of the screen
3428
3429 // Left
3430
2/2
✓ Branch 0 taken 10449 times.
✓ Branch 1 taken 14930619 times.
14941068 if(thisffc.x<-32)
3431 {
3432
2/2
✓ Branch 0 taken 253 times.
✓ Branch 1 taken 10196 times.
10449 if(scr->flags6&fWRAPAROUNDFF)
3433 {
3434 253 thisffc.x = wrap_right+(thisffc.x+32);
3435 253 thisffc.solid_update(false);
3436 253 thisffc.prev_changer_y = thisffc.y.getZLong();
3437 // Re-enable previous changer
3438 253 thisffc.changer_x = -1000;
3439 253 thisffc.changer_y = -1000;
3440 253 }
3441
2/2
✓ Branch 0 taken 10127 times.
✓ Branch 1 taken 69 times.
10196 else if(thisffc.x<-64)
3442 {
3443 69 zc_ffc_set(thisffc, 0);
3444 69 thisffc.flags&=~ffc_carryover;
3445 69 }
3446 10449 }
3447 // Right
3448
2/2
✓ Branch 0 taken 14930438 times.
✓ Branch 1 taken 181 times.
14930619 else if(thisffc.x>=wrap_right)
3449 {
3450
2/2
✓ Branch 0 taken 128 times.
✓ Branch 1 taken 53 times.
181 if(scr->flags6&fWRAPAROUNDFF)
3451 {
3452 128 thisffc.x = thisffc.x-wrap_right-32;
3453 128 thisffc.solid_update(false);
3454 128 thisffc.prev_changer_y = thisffc.y.getZLong();
3455 128 thisffc.changer_x = -1000;
3456 128 thisffc.changer_y = -1000;
3457 128 }
3458 else
3459 {
3460 53 zc_ffc_set(thisffc, 0);
3461 53 thisffc.flags&=~ffc_carryover;
3462 }
3463 181 }
3464
3465 // Top
3466
2/2
✓ Branch 0 taken 25480 times.
✓ Branch 1 taken 14915588 times.
14941068 if(thisffc.y<-32)
3467 {
3468
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 25472 times.
25480 if(scr->flags6&fWRAPAROUNDFF)
3469 {
3470 8 thisffc.y = wrap_bottom+(thisffc.y+32);
3471 8 thisffc.solid_update(false);
3472 8 thisffc.prev_changer_x = thisffc.x.getZLong();
3473 8 thisffc.changer_x = -1000;
3474 8 thisffc.changer_y = -1000;
3475 8 }
3476
2/2
✓ Branch 0 taken 25155 times.
✓ Branch 1 taken 317 times.
25472 else if(thisffc.y<-64)
3477 {
3478 317 zc_ffc_set(thisffc, 0);
3479 317 thisffc.flags&=~ffc_carryover;
3480 317 }
3481 25480 }
3482 // Bottom
3483
2/2
✓ Branch 0 taken 14914744 times.
✓ Branch 1 taken 844 times.
14915588 else if(thisffc.y>=wrap_bottom)
3484 {
3485
2/2
✓ Branch 0 taken 753 times.
✓ Branch 1 taken 91 times.
844 if(scr->flags6&fWRAPAROUNDFF)
3486 {
3487 753 thisffc.y = thisffc.y-wrap_bottom-32;
3488 753 thisffc.solid_update(false);
3489 753 thisffc.prev_changer_y = thisffc.x.getZLong();
3490 753 thisffc.changer_x = -1000;
3491 753 thisffc.changer_y = -1000;
3492 753 }
3493 else
3494 {
3495 91 zc_ffc_set(thisffc, 0);
3496 91 thisffc.flags&=~ffc_carryover;
3497 }
3498 844 }
3499 14941068 thisffc.solid_update();
3500 441782518 });
3501 14378197 }
3502 14402369 }
3503
3504 bool hitflag(int32_t x, int32_t y, int32_t flagtype, byte layers)
3505 {
3506 for(int q = 0; q < 7; ++q)
3507 {
3508 if(layers&(1<<q)) //if layer is to be checked
3509 if(MAPFLAG2(q-1,x,y)==flagtype||MAPCOMBOFLAG2(q-1,x,y)==flagtype) //matching flag
3510 return true;
3511 }
3512 return false;
3513 }
3514
3515 231 optional<int> nextscr(int screen, int dir)
3516 {
3517 231 auto [m, s] = nextscr2(cur_map, screen, dir);
3518
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 231 times.
231 if (m == -1) return nullopt;
3519 462 return (m<<7) + s;
3520 231 }
3521
3522 1058 std::pair<int32_t, int32_t> nextscr2(int32_t dir)
3523 {
3524 1058 int32_t map = cur_map;
3525
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1058 times.
1058 int32_t screen = screenscrolling ? scrolling_hero_screen : hero_screen;
3526 1058 return nextscr2(map, screen, dir);
3527 }
3528
3529 5576 std::pair<int32_t, int32_t> nextscr2(int map, int screen, int32_t dir)
3530 {
3531 5576 screen = screen_index_direction(screen, (direction)dir);
3532
3533 // need to check for screens on other maps, 's' not valid, etc.
3534 5576 int32_t index = (hero_scr->sidewarpindex >> (dir*2))&3;
3535
3536 // Fun fact: when a scrolling warp is triggered, this function
3537 // is never even called! - Saf
3538
2/2
✓ Branch 0 taken 3326 times.
✓ Branch 1 taken 2250 times.
6120 if(hero_scr->sidewarptype[index] == 3) // scrolling warp
3539 {
3540
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 482 times.
✓ Branch 2 taken 525 times.
✓ Branch 3 taken 546 times.
✓ Branch 4 taken 697 times.
2250 switch(dir)
3541 {
3542 case up:
3543
2/2
✓ Branch 0 taken 83 times.
✓ Branch 1 taken 399 times.
482 if(!(hero_scr->flags2&wfUP)) goto nowarp;
3544
3545 83 break;
3546
3547 case down:
3548
2/2
✓ Branch 0 taken 79 times.
✓ Branch 1 taken 446 times.
525 if(!(hero_scr->flags2&wfDOWN)) goto nowarp;
3549
3550 79 break;
3551
3552 case left:
3553
2/2
✓ Branch 0 taken 209 times.
✓ Branch 1 taken 337 times.
546 if(!(hero_scr->flags2&wfLEFT)) goto nowarp;
3554
3555 209 break;
3556
3557 case right:
3558
2/2
✓ Branch 0 taken 173 times.
✓ Branch 1 taken 524 times.
697 if(!(hero_scr->flags2&wfRIGHT)) goto nowarp;
3559
3560 173 break;
3561 }
3562
3563 544 map = DMaps[hero_scr->sidewarpdmap[index]].map;
3564 544 screen = hero_scr->sidewarpscr[index] + DMaps[hero_scr->sidewarpdmap[index]].xoff;
3565 544 }
3566
3567 nowarp:
3568
4/4
✓ Branch 0 taken 5512 times.
✓ Branch 1 taken 64 times.
✓ Branch 2 taken 112 times.
✓ Branch 3 taken 5400 times.
5576 if(screen<0||screen>=128)
3569 176 return {-1, -1};
3570
3571 5400 return {map, screen};
3572 5576 }
3573
3574 403 optional<int> nextscr_mi(int mi, int dir)
3575 {
3576 403 int map = mi/MAPSCRSNORMAL;
3577 403 int screen = mi%MAPSCRSNORMAL;
3578 403 auto [m, s] = nextscr2(map, screen, dir);
3579
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 402 times.
403 if (m == -1) return nullopt;
3580 804 return (m<<7) + s;
3581 403 }
3582
3583 2114 void bombdoor(int32_t x,int32_t y)
3584 {
3585
2/2
✓ Branch 0 taken 2094 times.
✓ Branch 1 taken 20 times.
2114 if (!is_in_world_bounds(x, y))
3586 20 return;
3587
3588 2094 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, 0);
3589 2094 mapscr* scr = rpos_handle.scr;
3590 2094 int screen = scr->screen;
3591 2902 auto [x0, y0] = translate_screen_coordinates_to_world(rpos_handle.screen);
3592 #define CHECK_RECT(x,y,rx1,ry1,rx2,ry2) (isinRect(x,y,x0+rx1,y0+ry1,x0+rx2,y0+ry2))
3593
3594
12/12
✓ Branch 0 taken 79 times.
✓ Branch 1 taken 2015 times.
✓ Branch 2 taken 10 times.
✓ Branch 3 taken 69 times.
✓ Branch 4 taken 10 times.
✓ Branch 5 taken 69 times.
✓ Branch 6 taken 10 times.
✓ Branch 7 taken 69 times.
✓ Branch 8 taken 10 times.
✓ Branch 9 taken 69 times.
✓ Branch 10 taken 10 times.
✓ Branch 11 taken 69 times.
2094 if(scr->door[0]==dBOMB && CHECK_RECT(x,y,100,0,139,48))
3595 {
3596 69 scr->door[0]=dBOMBED;
3597 69 putdoor(scr, scrollbuf, 0, dBOMBED);
3598 69 setmapflag(scr, mDOOR_UP);
3599 69 markBmap(-1, screen);
3600
3601
1/2
✓ Branch 0 taken 69 times.
✗ Branch 1 not taken.
69 if(auto v = nextscr(screen, up))
3602 {
3603 69 setmapflag_mi(*v, mDOOR_DOWN);
3604 69 markBmap(-1,*v-(get_currdmap()<<7));
3605 69 }
3606 69 }
3607
3608
12/12
✓ Branch 0 taken 49 times.
✓ Branch 1 taken 2045 times.
✓ Branch 2 taken 10 times.
✓ Branch 3 taken 39 times.
✓ Branch 4 taken 10 times.
✓ Branch 5 taken 39 times.
✓ Branch 6 taken 10 times.
✓ Branch 7 taken 39 times.
✓ Branch 8 taken 10 times.
✓ Branch 9 taken 39 times.
✓ Branch 10 taken 10 times.
✓ Branch 11 taken 39 times.
2094 if(scr->door[1]==dBOMB && CHECK_RECT(x,y,100,112,139,176))
3609 {
3610 39 scr->door[1]=dBOMBED;
3611 39 putdoor(scr, scrollbuf, 1, dBOMBED);
3612 39 setmapflag(scr, mDOOR_DOWN);
3613 39 markBmap(-1, rpos_handle.screen);
3614
3615
1/2
✓ Branch 0 taken 39 times.
✗ Branch 1 not taken.
39 if(auto v = nextscr(rpos_handle.screen, down))
3616 {
3617 39 setmapflag_mi(*v, mDOOR_UP);
3618 39 markBmap(-1,*v-(get_currdmap()<<7));
3619 39 }
3620 39 }
3621
3622
12/12
✓ Branch 0 taken 67 times.
✓ Branch 1 taken 2027 times.
✓ Branch 2 taken 16 times.
✓ Branch 3 taken 51 times.
✓ Branch 4 taken 16 times.
✓ Branch 5 taken 51 times.
✓ Branch 6 taken 16 times.
✓ Branch 7 taken 51 times.
✓ Branch 8 taken 16 times.
✓ Branch 9 taken 51 times.
✓ Branch 10 taken 16 times.
✓ Branch 11 taken 51 times.
2094 if(scr->door[2]==dBOMB && CHECK_RECT(x,y,0,60,48,98))
3623 {
3624 51 scr->door[2]=dBOMBED;
3625 51 putdoor(scr, scrollbuf, 2, dBOMBED);
3626 51 setmapflag(scr, mDOOR_LEFT);
3627 51 markBmap(-1, rpos_handle.screen);
3628
3629
1/2
✓ Branch 0 taken 51 times.
✗ Branch 1 not taken.
51 if(auto v = nextscr(rpos_handle.screen, left))
3630 {
3631 51 setmapflag_mi(*v, mDOOR_RIGHT);
3632 51 markBmap(-1,*v-(get_currdmap()<<7));
3633 51 }
3634 51 }
3635
3636
12/12
✓ Branch 0 taken 86 times.
✓ Branch 1 taken 2008 times.
✓ Branch 2 taken 14 times.
✓ Branch 3 taken 72 times.
✓ Branch 4 taken 14 times.
✓ Branch 5 taken 72 times.
✓ Branch 6 taken 14 times.
✓ Branch 7 taken 72 times.
✓ Branch 8 taken 14 times.
✓ Branch 9 taken 72 times.
✓ Branch 10 taken 14 times.
✓ Branch 11 taken 72 times.
2094 if(scr->door[3]==dBOMB && CHECK_RECT(x,y,192,60,240,98))
3637 {
3638 72 scr->door[3]=dBOMBED;
3639 72 putdoor(scr, scrollbuf, 3, dBOMBED);
3640 72 setmapflag(scr, mDOOR_RIGHT);
3641 72 markBmap(-1, rpos_handle.screen);
3642
3643
1/2
✓ Branch 0 taken 72 times.
✗ Branch 1 not taken.
72 if(auto v = nextscr(rpos_handle.screen, right))
3644 {
3645 72 setmapflag_mi(*v, mDOOR_LEFT);
3646 72 markBmap(-1,*v-(get_currdmap()<<7));
3647 72 }
3648 72 }
3649 2114 }
3650
3651 6384306538 void draw_cmb(BITMAP* dest, int32_t x, int32_t y, int32_t cid, int32_t cset,
3652 bool over, bool transp)
3653 {
3654 6384306538 auto& cmb = combobuf[cid];
3655
2/2
✓ Branch 0 taken 90743 times.
✓ Branch 1 taken 6384215795 times.
6384306538 if(cmb.animflags & AF_EDITOR_ONLY)
3656 90743 return;
3657
2/2
✓ Branch 0 taken 3309354865 times.
✓ Branch 1 taken 3074860930 times.
6384215795 if(over)
3658 {
3659
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3309354865 times.
3309354865 if(cmb.animflags & AF_TRANSPARENT)
3660 transp = !transp;
3661
2/2
✓ Branch 0 taken 319148412 times.
✓ Branch 1 taken 2990206453 times.
3309354865 if(transp)
3662 319148412 overcombotranslucent(dest, x, y, cid, cset, 128);
3663 2990206453 else overcombo(dest, x, y, cid, cset);
3664 3309354865 }
3665 3074860930 else putcombo(dest, x, y, cid, cset);
3666 6384306538 }
3667 6384314986 void draw_cmb_pos(BITMAP* dest, int32_t x, int32_t y, rpos_t rpos, int32_t cid,
3668 int32_t cset, byte layer, bool over, bool transp)
3669 {
3670
2/2
✓ Branch 0 taken 750736355 times.
✓ Branch 1 taken 5633578631 times.
6384314986 if (rpos != rpos_t::None)
3671 {
3672 5633578631 rpos_t plrpos = COMBOPOS_REGION_B(Hero.x+8, Hero.y+8);
3673
2/2
✓ Branch 0 taken 749524 times.
✓ Branch 1 taken 5632829107 times.
5633578631 if (plrpos != rpos_t::None)
3674 {
3675 5632829107 bool dosw = false;
3676
4/4
✓ Branch 0 taken 52860 times.
✓ Branch 1 taken 5632776247 times.
✓ Branch 2 taken 44412 times.
✓ Branch 3 taken 8448 times.
5632829107 if (rpos == hooked_comborpos && (hooked_layerbits & (1<<layer)))
3677 {
3678
1/2
✓ Branch 0 taken 8448 times.
✗ Branch 1 not taken.
8448 if(hooked_undercombos[layer] > -1)
3679 {
3680 draw_cmb(dest, x, y,
3681 hooked_undercombos[layer], hooked_undercombos[layer+7], over, transp);
3682 }
3683 8448 dosw = true;
3684 8448 }
3685
4/4
✓ Branch 0 taken 31973777 times.
✓ Branch 1 taken 5600846882 times.
✓ Branch 2 taken 8448 times.
✓ Branch 3 taken 31965329 times.
5632820659 else if (rpos == plrpos && (hooked_layerbits & (1<<(layer+8))))
3686 {
3687 8448 dosw = true;
3688 8448 }
3689
2/2
✓ Branch 0 taken 5632812211 times.
✓ Branch 1 taken 16896 times.
5632829107 if (dosw)
3690 {
3691
1/4
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 16896 times.
✗ Branch 3 not taken.
16896 switch (Hero.switchhookstyle)
3692 {
3693 default: case swPOOF:
3694 break; //Nothing special here
3695 case swFLICKER:
3696 {
3697
2/2
✓ Branch 0 taken 8448 times.
✓ Branch 1 taken 8448 times.
16896 if(abs(Hero.switchhookclk-33)&0b1000)
3698 8448 break; //Drawn this frame
3699 8448 return; //Not drawn this frame
3700 }
3701 case swRISE:
3702 {
3703 //Draw rising up
3704 y -= 8-(abs(Hero.switchhookclk-32)/4);
3705 break;
3706 }
3707 }
3708 8448 }
3709 5632820659 }
3710 5633570183 }
3711
3712 6384306538 draw_cmb(dest, x, y, cid, cset, over, transp);
3713 6384314986 }
3714
3715 // `draw_cmb_pos` only does meaningful work if the combo being drawn is within the bounds of
3716 // the `bmp` bitmap. However, even getting to the point where `puttile16` (for example) knows
3717 // to cull is somewhat expensive. Since it can only draw 16x16 pixels, we can do the equivalent
3718 // culling here by determining the rows/columns that are within the bitmap bounds. This nets
3719 // on the order of ~30 FPS in uncapped mode on my machine, depending on the viewport/region size.
3720 //
3721 // These two inequalities must be true for `draw_cmb_pos` to do anything useful:
3722 //
3723 // -16 < comboPositionX*16 + x < bitmapWidth
3724 // -16 < comboPositionY*16 + y < bitmapHeight
3725 //
3726 // The following start/end values are derived directly from the above.
3727 //
3728 // `x` and `y` are the offsets the combos will be drawn into the bitmap.
3729 39481806 static void get_bounds_for_draw_cmb_calls(BITMAP* bmp, int x, int y, int& start_x, int& end_x, int& start_y, int& end_y)
3730 {
3731 // if (bmp->clip)
3732 // {
3733 // start_x = MAX(0, ceil((bmp->cl - 15 - x) / 16.0));
3734 // end_x = MIN(16, ceil((bmp->cr - x) / 16.0));
3735 // start_y = MAX(0, ceil((bmp->ct - 15 - y) / 16.0));
3736 // end_y = MIN(11, ceil((bmp->cb - y) / 16.0));
3737 // return;
3738 // }
3739
3740
2/2
✓ Branch 0 taken 2169310 times.
✓ Branch 1 taken 37312496 times.
39481806 start_x = MAX(0, ceil((-15 - x) / 16.0));
3741
2/2
✓ Branch 0 taken 2178501 times.
✓ Branch 1 taken 37303305 times.
39481806 end_x = MIN(16, ceil((bmp->w - x) / 16.0));
3742
2/2
✓ Branch 0 taken 38092548 times.
✓ Branch 1 taken 1389258 times.
39481806 start_y = MAX(0, ceil((-15 - y) / 16.0));
3743
2/2
✓ Branch 0 taken 1678576 times.
✓ Branch 1 taken 37803230 times.
39481806 end_y = MIN(11, ceil((bmp->h - y) / 16.0));
3744 39481806 }
3745
3746 186960519 void do_ffc_layer(BITMAP* bmp, int32_t layer, const screen_handle_t& screen_handle, int32_t x, int32_t y)
3747 {
3748
1/2
✓ Branch 0 taken 186960519 times.
✗ Branch 1 not taken.
186960519 if(!show_ffcs) return;
3749 186960519 mapscr* scr = screen_handle.scr;
3750 186960519 mapscr* base_scr = screen_handle.base_scr;
3751
3752 186960519 y += playing_field_offset;
3753
3754 186960519 bool is_bg_layer = layer < -1;
3755
2/2
✓ Branch 0 taken 33926573 times.
✓ Branch 1 taken 153033946 times.
186960519 int real_layer = is_bg_layer ? abs(layer) : layer;
3756
2/2
✓ Branch 0 taken 186960519 times.
✓ Branch 1 taken 5581189773 times.
5768150292 for(int32_t i = (base_scr->numFFC()-1); i >= 0; --i)
3757 {
3758
2/2
✓ Branch 0 taken 5375692187 times.
✓ Branch 1 taken 205497586 times.
5581189773 if (base_scr->ffcs[i].data == 0)
3759 5375692187 continue;
3760
4/4
✓ Branch 0 taken 37360942 times.
✓ Branch 1 taken 168136644 times.
✓ Branch 2 taken 18682952 times.
✓ Branch 3 taken 18677990 times.
205497586 if(real_layer == 2 && (is_bg_layer != XOR(base_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG)))
3761 18677990 continue;
3762
4/4
✓ Branch 0 taken 37360942 times.
✓ Branch 1 taken 149458654 times.
✓ Branch 2 taken 18682952 times.
✓ Branch 3 taken 18677990 times.
186819596 else if (real_layer == 3 && (is_bg_layer != XOR(base_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG)))
3763 18677990 continue;
3764
4/4
✓ Branch 0 taken 149463616 times.
✓ Branch 1 taken 18677990 times.
✓ Branch 2 taken 18682952 times.
✓ Branch 3 taken 130780664 times.
168141606 if (real_layer > -1 && base_scr->ffcs[i].layer != real_layer)
3765 130780664 continue;
3766
3767
6/6
✓ Branch 0 taken 3008970 times.
✓ Branch 1 taken 34351972 times.
✓ Branch 2 taken 5110 times.
✓ Branch 3 taken 3003860 times.
✓ Branch 4 taken 2626 times.
✓ Branch 5 taken 2484 times.
37360942 if (screenscrolling && (base_scr->ffcs[i].flags & ffc_carryover) != 0 && screen_handle.screen != scrolling_hero_screen)
3768 2484 continue; //If scrolling, only draw carryover ffcs from newscr and not oldscr.
3769
3770 37358458 base_scr->ffcs[i].draw_ffc(bmp, x, y, (layer==-1));
3771 37358458 }
3772 186960519 }
3773 170937415 void _do_current_ffc_layer(BITMAP* bmp, int32_t layer)
3774 {
3775
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 170937415 times.
170937415 if(!show_ffcs) return;
3776 346453052 for_every_base_screen_in_region([&](mapscr* base_scr, unsigned int region_scr_x, unsigned int region_scr_y) {
3777 175515637 screen_handle_t handle = {base_scr, base_scr, base_scr->screen, 0};
3778 175515637 do_ffc_layer(bmp, layer, handle, 0, 0);
3779 175515637 });
3780 170937415 }
3781 75616832 void do_scrolling_layer(BITMAP *bmp, int32_t type, const screen_handle_t& screen_handle, int32_t x, int32_t y)
3782 {
3783 75616832 mapscr* scr = screen_handle.scr;
3784 75616832 mapscr* base_scr = screen_handle.base_scr;
3785
3786
4/4
✓ Branch 0 taken 60951502 times.
✓ Branch 1 taken 14665330 times.
✓ Branch 2 taken 14665330 times.
✓ Branch 3 taken 75616832 times.
75616832 if (type == -3 || type == -4)
3787 {
3788 29330660 y += playing_field_offset;
3789
3790
0/2
✗ Branch 0 not taken.
✗ Branch 1 not taken.
29330660 for(int32_t i = (base_scr->numFFC()-1); i >= 0; --i)
3791 {
3792 if (base_scr->ffcs[i].data == 0)
3793 continue;
3794
3795 if (screenscrolling && (base_scr->ffcs[i].flags & ffc_carryover) != 0 && screen_handle.screen != scrolling_hero_screen)
3796 continue; //If scrolling, only draw carryover ffcs from newscr and not oldscr.
3797
3798 base_scr->ffcs[i].draw_ffc(bmp, x, y, (type==-4));
3799 }
3800 return;
3801 }
3802
3803 75616832 x -= viewport.x;
3804 75616832 y -= viewport.y - playing_field_offset;
3805
3806 75616832 bool over = true, transp = false;
3807 75616832 int layer = screen_handle.layer;
3808
3809
7/8
✓ Branch 0 taken 55151077 times.
✓ Branch 1 taken 20465755 times.
✓ Branch 2 taken 13148696 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 34185284 times.
✓ Branch 5 taken 20965793 times.
✓ Branch 6 taken 3060005 times.
✓ Branch 7 taken 4257054 times.
75616832 switch(type ? type : layer)
3810 {
3811 case -2: //push blocks
3812
2/2
✓ Branch 0 taken 19519954 times.
✓ Branch 1 taken 14665330 times.
34185284 if (scr)
3813 {
3814
2/2
✓ Branch 0 taken 3435511904 times.
✓ Branch 1 taken 23710596 times.
3435005872 for(int32_t i=0; i<176; i++)
3815 {
3816 3435511904 int32_t mf=scr->sflag[i], mf2 = combobuf[scr->data[i]].flag;
3817
3818
10/10
✓ Branch 0 taken 3435341560 times.
✓ Branch 1 taken 170344 times.
✓ Branch 2 taken 3433869588 times.
✓ Branch 3 taken 1471972 times.
✓ Branch 4 taken 3433240605 times.
✓ Branch 5 taken 628983 times.
✓ Branch 6 taken 24420859 times.
✓ Branch 7 taken 3408819746 times.
✓ Branch 8 taken 42762999 times.
✓ Branch 9 taken 16705821 times.
3472559372 if(mf==mfPUSHUD || mf==mfPUSH4 || mf==mfPUSHED || ((mf>=mfPUSHLR)&&(mf<=mfPUSHRINS))
3819
6/8
✓ Branch 0 taken 3430359076 times.
✓ Branch 1 taken 21539330 times.
✓ Branch 2 taken 3430359076 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3430359076 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 37047468 times.
✓ Branch 7 taken 3393311608 times.
3433240605 || mf2==mfPUSHUD || mf2==mfPUSH4 || mf2==mfPUSHED || ((mf2>=mfPUSHLR)&&(mf2<=mfPUSHRINS)))
3820 {
3821
4/4
✓ Branch 0 taken 4772507 times.
✓ Branch 1 taken 695982 times.
✓ Branch 2 taken 3657 times.
✓ Branch 3 taken 4768850 times.
90994487 auto rpos = screenscrolling || ViewingMap ? rpos_t::None : POS_TO_RPOS(i, screen_handle.screen);
3822 5468489 draw_cmb_pos(bmp, x + COMBOX(i), y + COMBOY(i), rpos, scr->data[i], scr->cset[i], layer, true, false);
3823 5468489 }
3824 3415485918 }
3825 23710596 }
3826 38375926 return;
3827
3828 case -1: //over combo
3829
1/2
✓ Branch 0 taken 20965793 times.
✗ Branch 1 not taken.
20965793 if (scr)
3830 {
3831
2/2
✓ Branch 0 taken 3689979568 times.
✓ Branch 1 taken 20965793 times.
3710945361 for(int32_t i=0; i<176; i++)
3832 {
3833
2/2
✓ Branch 0 taken 3670703512 times.
✓ Branch 1 taken 19276056 times.
3689979568 if(combo_class_buf[combobuf[scr->data[i]].type].overhead)
3834 {
3835
4/4
✓ Branch 0 taken 15523213 times.
✓ Branch 1 taken 3752843 times.
✓ Branch 2 taken 22320 times.
✓ Branch 3 taken 15500893 times.
19276056 auto rpos = screenscrolling || ViewingMap ? rpos_t::None : POS_TO_RPOS(i, screen_handle.screen);
3836 19276056 draw_cmb_pos(bmp, x + COMBOX(i), y + COMBOY(i), rpos, scr->data[i], scr->cset[i], layer, true, false);
3837 19276056 }
3838 3689979568 }
3839 20965793 }
3840 20965793 return;
3841
3842 case 1:
3843 case 4:
3844 case 5:
3845 case 6:
3846
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 13148696 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
13148696 if(TransLayers || base_scr->layeropacity[layer-1]==255)
3847 {
3848
1/2
✓ Branch 0 taken 13148696 times.
✗ Branch 1 not taken.
13148696 if (scr)
3849 {
3850
2/2
✓ Branch 0 taken 11489485 times.
✓ Branch 1 taken 1659211 times.
13148696 if(base_scr->layeropacity[layer-1]!=255)
3851 1659211 transp = true;
3852 13148696 break;
3853 }
3854 }
3855 return;
3856
3857 case 2:
3858
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 3060005 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
3060005 if(TransLayers || base_scr->layeropacity[layer-1]==255)
3859 {
3860
1/2
✓ Branch 0 taken 3060005 times.
✗ Branch 1 not taken.
3060005 if (scr)
3861 {
3862
2/2
✓ Branch 0 taken 2840408 times.
✓ Branch 1 taken 219597 times.
3060005 if(base_scr->layeropacity[layer-1]!=255)
3863 219597 transp = true;
3864
3865
2/2
✓ Branch 0 taken 2931096 times.
✓ Branch 1 taken 128909 times.
3060005 if(XOR(base_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
3866 128909 over = false;
3867
3868 3060005 break;
3869 }
3870 }
3871 return;
3872
3873 case 3:
3874
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 4257054 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
4257054 if(TransLayers || base_scr->layeropacity[layer-1]==255)
3875 {
3876
1/2
✓ Branch 0 taken 4257054 times.
✗ Branch 1 not taken.
4257054 if (scr)
3877 {
3878
2/2
✓ Branch 0 taken 4183341 times.
✓ Branch 1 taken 73713 times.
4257054 if(base_scr->layeropacity[layer-1]!=255)
3879 73713 transp = true;
3880
3881
2/2
✓ Branch 0 taken 36654 times.
✓ Branch 1 taken 60483 times.
4257054 if(XOR(base_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG)
3882
2/2
✓ Branch 0 taken 97137 times.
✓ Branch 1 taken 4159917 times.
4257054 && !XOR(base_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
3883 60483 over = false;
3884
3885 4257054 break;
3886 }
3887 }
3888 return;
3889 }
3890
3891 int start_x, end_x, start_y, end_y;
3892 20465755 get_bounds_for_draw_cmb_calls(bmp, x, y, start_x, end_x, start_y, end_y);
3893
2/2
✓ Branch 0 taken 20465755 times.
✓ Branch 1 taken 216989831 times.
237455586 for (int cy = start_y; cy < end_y; cy++)
3894 {
3895
2/2
✓ Branch 0 taken 3283735479 times.
✓ Branch 1 taken 216989831 times.
3500725310 for (int cx = start_x; cx < end_x; cx++)
3896 {
3897 3283735479 int i = cx + cy*16;
3898
4/4
✓ Branch 0 taken 2905552252 times.
✓ Branch 1 taken 378183227 times.
✓ Branch 2 taken 10227360 times.
✓ Branch 3 taken 2895324892 times.
3283735479 auto rpos = screenscrolling || ViewingMap ? rpos_t::None : POS_TO_RPOS(i, screen_handle.screen);
3899 3283735479 draw_cmb_pos(bmp, x + COMBOX(i), y + COMBOY(i), rpos, scr->data[i], scr->cset[i], layer, over, transp);
3900 3283735479 }
3901 216989831 }
3902 60951502 }
3903
3904 269002203 bool lenscheck(mapscr* scr, int layer)
3905 {
3906
4/4
✓ Branch 0 taken 268823255 times.
✓ Branch 1 taken 178948 times.
✓ Branch 2 taken 178948 times.
✓ Branch 3 taken 269002203 times.
269002203 if(layer < 0 || layer > 6) return true;
3907
2/2
✓ Branch 0 taken 259588626 times.
✓ Branch 1 taken 9413577 times.
269002203 if(get_qr(qr_OLD_LENS_LAYEREFFECT))
3908 {
3909
2/2
✓ Branch 0 taken 209710465 times.
✓ Branch 1 taken 49878161 times.
259588626 if(!layer) return true;
3910
8/8
✓ Branch 0 taken 34922371 times.
✓ Branch 1 taken 174788094 times.
✓ Branch 2 taken 258970 times.
✓ Branch 3 taken 34663401 times.
✓ Branch 4 taken 143758 times.
✓ Branch 5 taken 163336 times.
✓ Branch 6 taken 326536 times.
✓ Branch 7 taken 34480623 times.
209710465 if((layer==(int32_t)(scr->lens_layer&7)+1) && ((scr->lens_layer&llLENSSHOWS && !lensclk) || (scr->lens_layer&llLENSHIDES && lensclk)))
3911 489872 return false;
3912 209268717 }
3913 else
3914 {
3915
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 9413577 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 9413577 times.
9413577 if((lensclk ? scr->lens_hide : scr->lens_show) & (1<<layer))
3916 return false;
3917 }
3918 218682294 return true;
3919 268823255 }
3920
3921 156158207 void do_layer(BITMAP *bmp, int32_t type, const screen_handle_t& screen_handle, int32_t x, int32_t y)
3922 {
3923 156158207 bool showlayer = true;
3924 156158207 mapscr* base_scr = screen_handle.base_scr;
3925 156158207 int layer = screen_handle.layer;
3926
2/2
✓ Branch 0 taken 42084449 times.
✓ Branch 1 taken 114073758 times.
156158207 int target = type ? type : layer;
3927
3/4
✓ Branch 0 taken 114073758 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 20230988 times.
✓ Branch 3 taken 21853461 times.
156158207 switch(target)
3928 {
3929 case -2:
3930
1/2
✓ Branch 0 taken 20230988 times.
✗ Branch 1 not taken.
20230988 if(!show_layer_push)
3931 showlayer = false;
3932 20230988 break;
3933
3934 case -1:
3935
1/2
✓ Branch 0 taken 21853461 times.
✗ Branch 1 not taken.
21853461 if(!show_layer_over)
3936 showlayer = false;
3937 21853461 break;
3938
3939 case 1: case 2: case 3:
3940 case 4: case 5: case 6:
3941 114073758 showlayer = show_layers[target];
3942 114073758 break;
3943 }
3944
3945
2/2
✓ Branch 0 taken 42084449 times.
✓ Branch 1 taken 114073758 times.
156158207 if(!type)
3946 {
3947
2/2
✓ Branch 0 taken 113937560 times.
✓ Branch 1 taken 136198 times.
114073758 if(!lenscheck(base_scr,layer))
3948 136198 showlayer = false;
3949 114073758 }
3950
3951
2/2
✓ Branch 0 taken 136198 times.
✓ Branch 1 taken 156022009 times.
156158207 if(showlayer)
3952 {
3953
6/6
✓ Branch 0 taken 61007625 times.
✓ Branch 1 taken 95014384 times.
✓ Branch 2 taken 20521878 times.
✓ Branch 3 taken 40485747 times.
✓ Branch 4 taken 56123 times.
✓ Branch 5 taken 20465755 times.
156022009 if (screen_handle.scr && (type || !(base_scr->hidelayers & (1 << (layer)))))
3954 {
3955 60951502 do_scrolling_layer(bmp, type, screen_handle, x, y);
3956
4/4
✓ Branch 0 taken 20465755 times.
✓ Branch 1 taken 40485747 times.
✓ Branch 2 taken 19233761 times.
✓ Branch 3 taken 1231994 times.
60951502 if(!type && !get_qr(qr_PUSHBLOCK_SPRITE_LAYER))
3957
2/2
✓ Branch 0 taken 1231418 times.
✓ Branch 1 taken 576 times.
1232570 if(mblock2.draw(bmp,layer))
3958 576 do_primitives(bmp, SPLAYER_MOVINGBLOCK);
3959 60951502 }
3960 156022009 }
3961 156158207 }
3962
3963 103025421 void do_layer_primitives(BITMAP *bmp, int32_t layer)
3964 {
3965 103025421 bool showlayer = true;
3966
3967
2/4
✓ Branch 0 taken 103025421 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 103025421 times.
103025421 if(layer >= 0 && layer <= 6)
3968 {
3969 103025421 showlayer = show_layers[layer];
3970
3971
2/2
✓ Branch 0 taken 102898819 times.
✓ Branch 1 taken 126602 times.
103025421 if(!lenscheck(origin_scr,layer))
3972 126602 showlayer = false;
3973 103025421 }
3974
3975
2/2
✓ Branch 0 taken 126602 times.
✓ Branch 1 taken 102898819 times.
103025421 if (showlayer)
3976 102898819 do_primitives(bmp, layer);
3977 103025421 }
3978
3979 // Called by do_walkflags
3980 void put_walkflags(BITMAP *dest,int32_t x,int32_t y,int32_t xofs,int32_t yofs, word cmbdat,int32_t lyr)
3981 {
3982 newcombo const &c = combobuf[cmbdat];
3983
3984 if (c.type == cBRIDGE && get_qr(qr_OLD_BRIDGE_COMBOS)) return;
3985
3986 int32_t xx = x-xofs;
3987 int32_t yy = y+playing_field_offset-yofs;
3988
3989 int32_t bridgedetected = 0;
3990
3991 for(int32_t i=0; i<4; i++)
3992 {
3993 int32_t tx=((i&2)<<2)+xx - viewport.x;
3994 int32_t ty=((i&1)<<3)+yy - viewport.y;
3995 int32_t tx2=((i&2)<<2)+x - viewport.x;
3996 int32_t ty2=((i&1)<<3)+y - viewport.y;
3997 for (int32_t j = lyr-1; j <= 1; j++)
3998 {
3999 if (get_qr(qr_OLD_BRIDGE_COMBOS))
4000 {
4001 if (combobuf[MAPCOMBO2(j,tx2,ty2)].type == cBRIDGE && !_walkflag_layer(tx2,ty2,j))
4002 {
4003 bridgedetected |= (1<<i);
4004 }
4005 }
4006 else
4007 {
4008 if (combobuf[MAPCOMBO2(j,tx2,ty2)].type == cBRIDGE && _effectflag_layer(tx2,ty2,j))
4009 {
4010 bridgedetected |= (1<<i);
4011 }
4012 }
4013 }
4014 if ((bridgedetected & (1<<i)))
4015 {
4016 if (i >= 3) break;
4017 else continue;
4018 }
4019 bool doladdercheck = true;
4020
4021 if ((c.walk&(1<<(i+4))) && ((c.walk&(1<<i) && ((c.usrflags&cflag4)) && c.type == cWATER) || c.type == cSHALLOWWATER))
4022 {
4023 for(int32_t k=0; k<8; k+=2)
4024 for(int32_t j=0; j<8; j+=2)
4025 if(((k+j)/2)%2)
4026 rectfill(dest,tx+k,ty+j,tx+k+1,ty+j+1,makecol(85,85,255));
4027 }
4028 if (iswater_type(c.type) && !DRIEDLAKE && !((c.walk&(1<<(i+4))) && ((c.walk&(1<<i) && ((c.usrflags&cflag3) || (c.usrflags&cflag4)) && c.type == cWATER)))) //Yes, I realize this is horribly inaccurate; the alternative is the game chugging every time you turn on walk cheats.
4029 {
4030 if (get_qr(qr_NO_SOLID_SWIM)) doladdercheck = false;
4031 if((lyr==0 || (get_qr(qr_WATER_ON_LAYER_1) && lyr == 1) || (get_qr(qr_WATER_ON_LAYER_2) && lyr == 2)) && get_qr(qr_DROWN))
4032 rectfill(dest,tx,ty,tx+7,ty+7,makecol(85,85,255));
4033 else rectfill(dest,tx,ty,tx+7,ty+7,makecol(170,170,170));
4034 }
4035
4036 if(c.walk&(1<<i) && !(iswater_type(c.type) && DRIEDLAKE) && !((c.walk&(1<<(i+4))) && ((c.walk&(1<<i) && ((c.usrflags&cflag3) || (c.usrflags&cflag4)) && c.type == cWATER)))) // Check for dried lake (watertype && not water)
4037 {
4038 if(c.type==cLADDERHOOKSHOT && isstepable(cmbdat) && ishookshottable(xx,yy))
4039 {
4040 for(int32_t k=0; k<8; k+=2)
4041 for(int32_t j=0; j<8; j+=2)
4042 rectfill(dest,tx+k,ty+j,tx+k+1,ty+j+1,((k+j)/2)%2 ? makecol(165,105,8) : makecol(170,170,170));
4043 }
4044 else
4045 {
4046 int32_t color = makecol(178,36,36);
4047
4048 if(isstepable(cmbdat)&& (!doladdercheck))
4049 color=makecol(165,105,8);
4050 else if((c.type==cHOOKSHOTONLY || c.type==cLADDERHOOKSHOT) && ishookshottable(xx,yy))
4051 color=makecol(170,170,170);
4052
4053 rectfill(dest,tx,ty,tx+7,ty+7,color);
4054 }
4055 }
4056 }
4057
4058 // Draw damage combos
4059 bool dmg = combo_class_buf[combobuf[MAPCOMBO2(-1,xx,yy)].type].modify_hp_amount
4060 || combo_class_buf[combobuf[MAPCOMBO2(0,xx,yy)].type].modify_hp_amount
4061 || combo_class_buf[combobuf[MAPCOMBO2(1,xx,yy)].type].modify_hp_amount;
4062
4063 if(dmg)
4064 {
4065 int32_t color = makecol(255,255,0);
4066 if (bridgedetected <= 0)
4067 {
4068 for(int32_t k=0; k<16; k+=2)
4069 for(int32_t j=0; j<16; j+=2)
4070 if(((k+j)/2)%2)
4071 {
4072 int32_t x0 = x - viewport.x;
4073 int32_t y0 = y - viewport.y;
4074 rectfill(dest,x0+k,y0+j,x0+k+1,y0+j+1,color);
4075 }
4076 }
4077 else
4078 {
4079 for(int32_t i=0; i<4; i++)
4080 {
4081 if (!(bridgedetected & (1<<i)))
4082 {
4083 int32_t tx=((i&2)<<2)+x - viewport.x;
4084 int32_t ty=((i&1)<<3)+y - viewport.y;
4085 for(int32_t k=0; k<8; k+=2)
4086 for(int32_t j=0; j<8; j+=2)
4087 if((k+j)%4 < 2) rectfill(dest,tx+k,ty+j,tx+k+1,ty+j+1,color);
4088 }
4089 }
4090 }
4091 }
4092 }
4093 static void put_walkflags_a5(int32_t x, int32_t y, word cmbdat, int32_t lyr)
4094 {
4095 ALLEGRO_COLOR col_solid = al_map_rgba(178,36,36,info_opacity);
4096 ALLEGRO_COLOR col_water1 = al_map_rgba(85,85,255,info_opacity);
4097 ALLEGRO_COLOR col_lhook = al_map_rgba(170,170,170,info_opacity);
4098 ALLEGRO_COLOR col_stepable = al_map_rgba(165,105,8,info_opacity);
4099 ALLEGRO_COLOR col_dmg = al_map_rgba(255,255,0,info_opacity);
4100 newcombo const &c = combobuf[cmbdat];
4101
4102 if (c.type == cBRIDGE && get_qr(qr_OLD_BRIDGE_COMBOS)) return;
4103
4104 int32_t xx = x-viewport.x;
4105 int32_t yy = y+playing_field_offset-viewport.y;
4106
4107 int32_t bridgedetected = 0;
4108
4109 // Draw damage combos
4110 bool dmg = combo_class_buf[c.type].modify_hp_amount;
4111
4112 for(int32_t i=0; i<4; i++)
4113 {
4114 int32_t tx=((i&2)<<2)+xx;
4115 int32_t ty=((i&1)<<3)+yy;
4116 int32_t tx2=((i&2)<<2)+x;
4117 int32_t ty2=((i&1)<<3)+y;
4118 for (int32_t m = lyr-1; m <= 1; m++)
4119 {
4120 if (get_qr(qr_OLD_BRIDGE_COMBOS))
4121 {
4122 if (m >= 0 && combobuf[MAPCOMBO2(m, tx2, ty2)].type == cBRIDGE && !_walkflag_layer(tx2, ty2, m))
4123 {
4124 bridgedetected |= (1<<i);
4125 }
4126 }
4127 else
4128 {
4129 if (m >= 0 && combobuf[MAPCOMBO2(m, tx2, ty2)].type == cBRIDGE && _effectflag_layer(tx2, ty2, m))
4130 {
4131 bridgedetected |= (1<<i);
4132 }
4133 }
4134 }
4135 if ((bridgedetected & (1<<i)))
4136 continue;
4137 bool doladdercheck = true;
4138
4139 if ((c.walk&(1<<(i+4))) && ((c.walk&(1<<i) && ((c.usrflags&cflag4)) && c.type == cWATER) || c.type == cSHALLOWWATER))
4140 {
4141 for(int32_t k=0; k<8; k+=2)
4142 for(int32_t j=0; j<8; j+=2)
4143 if(((k+j)/2)%2)
4144 al_draw_filled_rectangle(tx+k,ty+j,tx+k+2,ty+j+2,col_water1);
4145 }
4146 if (iswater_type(c.type) && !DRIEDLAKE && !((c.walk&(1<<(i+4))) && ((c.walk&(1<<i) && ((c.usrflags&cflag3) || (c.usrflags&cflag4)) && c.type == cWATER)))) //Yes, I realize this is horribly inaccurate; the alternative is the game chugging every time you turn on walk cheats.
4147 {
4148 if (get_qr(qr_NO_SOLID_SWIM)) doladdercheck = false;
4149 if((lyr==0 || (get_qr(qr_WATER_ON_LAYER_1) && lyr == 1) || (get_qr(qr_WATER_ON_LAYER_2) && lyr == 2)) && get_qr(qr_DROWN))
4150 al_draw_filled_rectangle(tx,ty,tx+8,ty+8,col_water1);
4151 else al_draw_filled_rectangle(tx,ty,tx+8,ty+8,col_lhook);
4152 }
4153
4154 if(c.walk&(1<<i) && !(iswater_type(c.type) && DRIEDLAKE) && !((c.walk&(1<<(i+4))) && ((c.walk&(1<<i) && ((c.usrflags&cflag3) || (c.usrflags&cflag4)) && c.type == cWATER)))) // Check for dried lake (watertype && not water)
4155 {
4156 if(c.type==cLADDERHOOKSHOT && isstepable(cmbdat) && ishookshottable(xx,yy))
4157 {
4158 for(int32_t k=0; k<8; k+=2)
4159 for(int32_t j=0; j<8; j+=2)
4160 al_draw_filled_rectangle(tx+k,ty+j,tx+k+2,ty+j+2,((k+j)/2)%2 ? col_stepable : col_lhook);
4161 }
4162 else
4163 {
4164 ALLEGRO_COLOR* color = &col_solid;
4165
4166 if(isstepable(cmbdat)&& (!doladdercheck))
4167 color=&col_stepable;
4168 else if((c.type==cHOOKSHOTONLY || c.type==cLADDERHOOKSHOT) && ishookshottable(xx,yy))
4169 color=&col_lhook;
4170
4171 al_draw_filled_rectangle(tx,ty,tx+8,ty+8,*color);
4172 }
4173 }
4174
4175 if(dmg)
4176 {
4177 for(int32_t k=0; k<8; k+=2)
4178 for(int32_t j=0; j<8; j+=2)
4179 if((k+j)%4 < 2) al_draw_filled_rectangle(tx+k,ty+j,tx+k+2,ty+j+2,col_dmg);
4180 }
4181 }
4182 }
4183
4184 void put_effectflags(BITMAP *dest,int32_t x,int32_t y,int32_t xofs,int32_t yofs, word cmbdat,int32_t lyr)
4185 {
4186 newcombo const &c = combobuf[cmbdat];
4187
4188 int32_t xx = x-xofs-viewport.x;
4189 int32_t yy = y+playing_field_offset-yofs-viewport.y;
4190
4191 for(int32_t i=0; i<4; i++)
4192 {
4193 int32_t tx=((i&2)<<2)+xx;
4194 int32_t ty=((i&1)<<3)+yy;
4195
4196 if(((c.walk>>4)&(1<<i)) && c.type != cNONE)
4197 {
4198 int32_t color = vc(10);
4199
4200 rectfill(dest,tx,ty,tx+7,ty+7,color);
4201 }
4202 }
4203 }
4204 static void put_effectflags_a5(int32_t x, int32_t y, word cmbdat, int32_t lyr)
4205 {
4206 ALLEGRO_COLOR col_eff = al_map_rgba(85,255,85,info_opacity);
4207 newcombo const &c = combobuf[cmbdat];
4208
4209 int32_t xx = x-viewport.x;
4210 int32_t yy = y+playing_field_offset-viewport.y;
4211
4212 for(int32_t i=0; i<4; i++)
4213 {
4214 int32_t tx=((i&2)<<2)+xx;
4215 int32_t ty=((i&1)<<3)+yy;
4216
4217 if(((c.walk>>4)&(1<<i)) && c.type != cNONE)
4218 {
4219 al_draw_filled_rectangle(tx,ty,tx+8,ty+8,col_eff);
4220 }
4221 }
4222 }
4223
4224 void draw_ladder_platform(BITMAP* dest, int32_t x, int32_t y, int32_t c)
4225 {
4226 for(auto cx = 0; cx < 256; cx += 16)
4227 {
4228 for(auto cy = 0; cy < 176; cy += 16)
4229 {
4230 if(isSVLadder(cx,cy))
4231 {
4232 auto nx = cx+x, ny = cy+y;
4233 if(cy && !isSVLadder(cx,cy-16))
4234 line(dest,nx,ny,nx+15,ny,c);
4235 rectfill(dest,nx,ny,nx+3,ny+15,c);
4236 rectfill(dest,nx+12,ny,nx+15,ny+15,c);
4237 rectfill(dest,nx+4,ny+2,nx+11,ny+5,c);
4238 rectfill(dest,nx+4,ny+10,nx+11,ny+13,c);
4239 }
4240 else if(isSVPlatform(cx,cy))
4241 {
4242 line(dest,cx+x,cy+y,cx+x+15,cy+y,c);
4243 }
4244 }
4245 }
4246 }
4247 void draw_ladder_platform_a5(int32_t x, int32_t y, ALLEGRO_COLOR c)
4248 {
4249 for(auto cx = 0; cx < 256; cx += 16)
4250 {
4251 for(auto cy = 0; cy < 176; cy += 16)
4252 {
4253 if(isSVLadder(cx,cy))
4254 {
4255 auto nx = cx+x, ny = cy+y;
4256 if(cy && !isSVLadder(cx,cy-16))
4257 al_draw_line(nx,ny,nx+15,ny,c,1);
4258 al_draw_filled_rectangle(nx,ny,nx+4,ny+16,c);
4259 al_draw_filled_rectangle(nx+12,ny,nx+16,ny+16,c);
4260 al_draw_filled_rectangle(nx+4,ny+2,nx+12,ny+6,c);
4261 al_draw_filled_rectangle(nx+4,ny+10,nx+12,ny+14,c);
4262 }
4263 else if(isSVPlatform(cx,cy))
4264 {
4265 al_draw_line(cx+x,cy+y,cx+x+15,cy+y,c,1);
4266 }
4267 }
4268 }
4269 }
4270
4271 // Walkflags L4 cheat
4272 void do_walkflags(const screen_handles_t& screen_handles, int32_t x, int32_t y)
4273 {
4274 if (!show_walkflags)
4275 return;
4276
4277 start_info_bmp();
4278
4279 mapscr* scr = screen_handles[0].scr;
4280 for(int32_t i=0; i<176; i++)
4281 {
4282 put_walkflags_a5(((i&15)<<4) + x, (i&0xF0) + y, scr->data[i], 0);
4283 }
4284
4285 for(int32_t k=0; k<2; k++)
4286 {
4287 scr = screen_handles[k + 1].scr;
4288
4289 if (scr)
4290 {
4291 for(int32_t i=0; i<176; i++)
4292 {
4293 put_walkflags_a5(((i&15)<<4) + x, (i&0xF0) + y, scr->data[i], k%2+1);
4294 }
4295 }
4296 }
4297
4298 end_info_bmp();
4299 }
4300
4301 void do_walkflags(int32_t x, int32_t y)
4302 {
4303 if (!show_walkflags)
4304 return;
4305
4306 x += -viewport.x;
4307 y += playing_field_offset - viewport.y;
4308
4309 start_info_bmp();
4310
4311 draw_ladder_platform_a5(x,y,al_map_rgba(165,105,8,info_opacity));
4312 draw_solid_objects_a5(x,y,al_map_rgba(178,36,36,info_opacity));
4313 draw_slopes_a5(x,y,al_map_rgba(255,85,255,info_opacity));
4314
4315 end_info_bmp();
4316 }
4317
4318 // Effectflags L4 cheat
4319 void do_effectflags(mapscr* scr, int32_t x, int32_t y)
4320 {
4321 if(show_effectflags)
4322 {
4323 start_info_bmp();
4324
4325 for(int32_t i=0; i<176; i++)
4326 {
4327 put_effectflags_a5(((i&15)<<4) + x, (i&0xF0) + y, scr->data[i], 0);
4328 }
4329
4330 end_info_bmp();
4331 }
4332 }
4333
4334 272141 void calc_darkroom_combos(mapscr* scr, int offx, int offy)
4335 {
4336 272141 int map = scr->map;
4337 272141 int screen = scr->screen;
4338
4339
2/2
✓ Branch 0 taken 1904987 times.
✓ Branch 1 taken 272141 times.
2177128 for(int32_t lyr = 0; lyr < 7; ++lyr)
4340 {
4341 1904987 mapscr* scr = get_scr_layer(map, screen, lyr);
4342
2/2
✓ Branch 0 taken 780869 times.
✓ Branch 1 taken 1124118 times.
1904987 if (!scr->is_valid()) continue;
4343
4344
2/2
✓ Branch 0 taken 137432944 times.
✓ Branch 1 taken 780869 times.
138213813 for(int32_t q = 0; q < 176; ++q)
4345 {
4346 137432944 newcombo const& cmb = combobuf[scr->data[q]];
4347
2/2
✓ Branch 0 taken 136828325 times.
✓ Branch 1 taken 604619 times.
137432944 if(cmb.type == cTORCH)
4348 {
4349 604619 do_torch_combo(cmb, COMBOX(q)+8+offx, COMBOY(q)+8+offy, darkscr_bmp);
4350 604619 }
4351 137432944 }
4352 780869 }
4353 272141 }
4354
4355 272141 void calc_darkroom_ffcs(mapscr* scr, int offx, int offy)
4356 {
4357 272141 word c = scr->numFFC();
4358
2/2
✓ Branch 0 taken 537406 times.
✓ Branch 1 taken 272141 times.
809547 for(int q = 0; q < c; ++q)
4359 {
4360 537406 newcombo const& cmb = combobuf[scr->ffcs[q].data];
4361
2/2
✓ Branch 0 taken 522598 times.
✓ Branch 1 taken 14808 times.
537406 if(cmb.type == cTORCH)
4362 {
4363 14808 int cx = scr->ffcs[q].x.getInt()+(scr->ffEffectWidth(q)/2)+offx;
4364 14808 int cy = (scr->ffcs[q].y.getInt())+(scr->ffEffectHeight(q)/2)+offy;
4365 14808 do_torch_combo(cmb, cx, cy, darkscr_bmp);
4366 14808 }
4367 537406 }
4368 272141 }
4369
4370 struct nearby_screen_t
4371 {
4372 int screen;
4373 int offx;
4374 int offy;
4375 screen_handles_t screen_handles;
4376 };
4377 typedef std::vector<nearby_screen_t> nearby_screens_t;
4378
4379 15487811 static nearby_screens_t get_nearby_screens_non_scrolling_region()
4380 {
4381 15487811 nearby_screens_t nearby_screens;
4382
4383 15487811 mapscr* base_scr = origin_scr;
4384
1/2
✓ Branch 0 taken 15487811 times.
✗ Branch 1 not taken.
15487811 auto& nearby_screen = nearby_screens.emplace_back();
4385 15487811 nearby_screen.screen = cur_screen;
4386
1/2
✓ Branch 0 taken 15487811 times.
✗ Branch 1 not taken.
15487811 nearby_screen.screen_handles = create_screen_handles(base_scr);
4387
4388 15487811 return nearby_screens;
4389
1/2
✓ Branch 0 taken 15487811 times.
✗ Branch 1 not taken.
15487811 }
4390
4391 48296 static nearby_screens_t get_nearby_screens_scrolling_region()
4392 {
4393 48296 nearby_screens_t nearby_screens;
4394
4395
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 int screens_x0 = viewport.left() / 256;
4396
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 int screens_x1 = (viewport.right() - 1) / 256;
4397
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 int screens_y0 = viewport.top() / 176;
4398
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 int screens_y1 = (viewport.bottom() - 1) / 176;
4399
4400
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 screens_x0 = std::clamp(screens_x0, 0, 15);
4401
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 screens_x1 = std::clamp(screens_x1, 0, 15);
4402
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 screens_y0 = std::clamp(screens_y0, 0, 8);
4403
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 screens_y1 = std::clamp(screens_y1, 0, 8);
4404
4405
2/2
✓ Branch 0 taken 48296 times.
✓ Branch 1 taken 79928 times.
128224 for (int x = screens_x0; x <= screens_x1; x++)
4406 {
4407
2/2
✓ Branch 0 taken 169672 times.
✓ Branch 1 taken 79928 times.
249600 for (int y = screens_y0; y <= screens_y1; y++)
4408 {
4409 169672 int screen = cur_screen + x + y*16;
4410
1/2
✓ Branch 0 taken 169672 times.
✗ Branch 1 not taken.
169672 if (!is_in_current_region(screen)) continue;
4411
4412
1/2
✓ Branch 0 taken 169672 times.
✗ Branch 1 not taken.
169672 mapscr* base_scr = get_scr(screen);
4413
1/2
✓ Branch 0 taken 169672 times.
✗ Branch 1 not taken.
169672 if (!base_scr->is_valid()) continue;
4414
4415
1/2
✓ Branch 0 taken 169672 times.
✗ Branch 1 not taken.
169672 auto [offx, offy] = translate_screen_coordinates_to_world(screen);
4416
4417
1/2
✓ Branch 0 taken 169672 times.
✗ Branch 1 not taken.
169672 auto& nearby_screen = nearby_screens.emplace_back();
4418 169672 nearby_screen.screen = screen;
4419 169672 nearby_screen.offx = offx;
4420 169672 nearby_screen.offy = offy;
4421
1/2
✓ Branch 0 taken 169672 times.
✗ Branch 1 not taken.
169672 nearby_screen.screen_handles = create_screen_handles(base_scr);
4422 169672 }
4423 79928 }
4424
4425 48296 return nearby_screens;
4426
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 }
4427
4428 3658 static nearby_screens_t get_nearby_screens_smooth_maze()
4429 {
4430 3658 nearby_screens_t nearby_screens;
4431
4432
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 int screens_x0 = viewport.left() / 256;
4433
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 int screens_x1 = (viewport.right() - 1) / 256;
4434
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 int screens_y0 = viewport.top() / 176;
4435
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 int screens_y1 = (viewport.bottom() - 1) / 176;
4436
4437
2/4
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3658 times.
✗ Branch 3 not taken.
3658 if (viewport.left() < 0) screens_x0--;
4438
2/4
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3658 times.
✗ Branch 3 not taken.
3658 if (viewport.top() < 0) screens_y0--;
4439
4440
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 7308 times.
10966 for (int x = screens_x0; x <= screens_x1; x++)
4441 {
4442
2/2
✓ Branch 0 taken 18600 times.
✓ Branch 1 taken 7308 times.
25908 for (int y = screens_y0; y <= screens_y1; y++)
4443 {
4444 18600 int screen = -1;
4445 mapscr* base_scr;
4446 int offx, offy;
4447
4448 18600 mapscr* maze_scr = maze_state.scr;
4449 18600 int maze_screen = maze_scr->screen;
4450
1/2
✓ Branch 0 taken 18600 times.
✗ Branch 1 not taken.
18600 int maze_screen_x = get_region_relative_dx(maze_screen);
4451
1/2
✓ Branch 0 taken 18600 times.
✗ Branch 1 not taken.
18600 int maze_screen_y = get_region_relative_dy(maze_screen);
4452 18600 int maze_screen_dx = x - maze_screen_x;
4453 18600 int maze_screen_dy = y - maze_screen_y;
4454 18600 int exitdir = maze_scr->exitdir;
4455
4456 bool should_draw_maze_screen;
4457
2/2
✓ Branch 0 taken 9052 times.
✓ Branch 1 taken 9548 times.
18600 if (maze_state.lost)
4458 {
4459 9548 should_draw_maze_screen = true;
4460 9548 }
4461 else
4462 {
4463 9052 should_draw_maze_screen = true;
4464
4/6
✓ Branch 0 taken 9052 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6844 times.
✓ Branch 3 taken 2208 times.
✓ Branch 4 taken 6844 times.
✗ Branch 5 not taken.
9052 should_draw_maze_screen &= XY_DELTA_TO_DIR(maze_screen_dx, 0) != exitdir && XY_DELTA_TO_DIR(0, maze_screen_dy) != exitdir;
4465
2/2
✓ Branch 0 taken 3850 times.
✓ Branch 1 taken 5202 times.
9052 if (maze_state.enter_dir != dir_invalid)
4466
4/6
✓ Branch 0 taken 3850 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3304 times.
✓ Branch 3 taken 546 times.
✓ Branch 4 taken 3304 times.
✗ Branch 5 not taken.
3850 should_draw_maze_screen &= XY_DELTA_TO_DIR(maze_screen_dx, 0) != maze_state.enter_dir && XY_DELTA_TO_DIR(0, maze_screen_dy) != maze_state.enter_dir;
4467 }
4468
4469
2/2
✓ Branch 0 taken 16048 times.
✓ Branch 1 taken 2552 times.
18600 if (should_draw_maze_screen)
4470 {
4471 16048 screen = maze_state.scr->screen;
4472 16048 base_scr = maze_state.scr;
4473
1/2
✓ Branch 0 taken 16048 times.
✗ Branch 1 not taken.
16048 std::tie(offx, offy) = translate_screen_coordinates_to_world(cur_screen + x + y*16);
4474 16048 }
4475
4476
2/2
✓ Branch 0 taken 16048 times.
✓ Branch 1 taken 2552 times.
18600 if (screen == -1)
4477 {
4478 2552 screen = cur_screen + x + y*16;
4479
1/2
✓ Branch 0 taken 2552 times.
✗ Branch 1 not taken.
2552 if (!is_in_current_region(screen)) continue;
4480
4481
1/2
✓ Branch 0 taken 2552 times.
✗ Branch 1 not taken.
2552 base_scr = get_scr(screen);
4482
1/2
✓ Branch 0 taken 2552 times.
✗ Branch 1 not taken.
2552 if (!base_scr->is_valid()) continue;
4483
4484
1/2
✓ Branch 0 taken 2552 times.
✗ Branch 1 not taken.
2552 std::tie(offx, offy) = translate_screen_coordinates_to_world(screen);
4485 2552 }
4486
4487
1/2
✓ Branch 0 taken 18600 times.
✗ Branch 1 not taken.
18600 auto& nearby_screen = nearby_screens.emplace_back();
4488 18600 nearby_screen.screen = screen;
4489 18600 nearby_screen.offx = offx;
4490 18600 nearby_screen.offy = offy;
4491
1/2
✓ Branch 0 taken 18600 times.
✗ Branch 1 not taken.
18600 nearby_screen.screen_handles = create_screen_handles(base_scr);
4492 18600 }
4493 7308 }
4494
4495 3658 return nearby_screens;
4496
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 }
4497
4498 15539765 static nearby_screens_t get_nearby_screens()
4499 {
4500
4/4
✓ Branch 0 taken 9214 times.
✓ Branch 1 taken 15530551 times.
✓ Branch 2 taken 3658 times.
✓ Branch 3 taken 5556 times.
15539765 if (maze_state.active && maze_state.loopy)
4501 3658 return get_nearby_screens_smooth_maze();
4502
4503
2/2
✓ Branch 0 taken 48296 times.
✓ Branch 1 taken 15487811 times.
15536107 if (is_in_scrolling_region())
4504 48296 return get_nearby_screens_scrolling_region();
4505
4506 15487811 return get_nearby_screens_non_scrolling_region();
4507 15539765 }
4508
4509 202038438 static void for_every_nearby_screen(const nearby_screens_t& nearby_screens, const std::function <void (screen_handles_t, int, int, int)>& fn)
4510 {
4511
2/2
✓ Branch 0 taken 203823040 times.
✓ Branch 1 taken 202038438 times.
405861478 for (auto& nearby_screen : nearby_screens)
4512 203823040 fn(nearby_screen.screen_handles, nearby_screen.screen, nearby_screen.offx, nearby_screen.offy);
4513 202038438 }
4514
4515 124318120 static void draw_msgstr(byte layer, BITMAP* dest = nullptr)
4516 {
4517
2/2
✓ Branch 0 taken 15539765 times.
✓ Branch 1 taken 108778355 times.
124318120 if(layer != msgstr_layer) return;
4518
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 if(!dest) dest = framebuf;
4519
4520
2/2
✓ Branch 0 taken 679438 times.
✓ Branch 1 taken 14860327 times.
15539765 if(!(msg_bg_display_buf->clip))
4521 {
4522 679438 blit_msgstr_bg(dest,0,0,0,playing_field_offset,256,176);
4523 679438 }
4524
4525
2/2
✓ Branch 0 taken 679438 times.
✓ Branch 1 taken 14860327 times.
15539765 if(!(msg_portrait_display_buf->clip))
4526 {
4527 679438 blit_msgstr_prt(dest,0,0,0,playing_field_offset,256,176);
4528 679438 }
4529
4530
2/2
✓ Branch 0 taken 692845 times.
✓ Branch 1 taken 14846920 times.
15539765 if(!(msg_txt_display_buf->clip))
4531 {
4532 692845 blit_msgstr_fg(dest,0,0,0,playing_field_offset,256,176);
4533 692845 }
4534 124318120 }
4535
4536 static void putscrdoors(const nearby_screens_t& nearby_screens, BITMAP *dest, int32_t x, int32_t y);
4537
4538 62159060 static void set_draw_screen_clip(BITMAP* bmp)
4539 {
4540 62159060 set_clip_rect(bmp, draw_screen_clip_rect_x1, draw_screen_clip_rect_y1, draw_screen_clip_rect_x2, draw_screen_clip_rect_y2);
4541 62159060 }
4542
4543 46119039 void draw_screen(bool showhero, bool runGeneric)
4544 {
4545 46119039 clear_info_bmp();
4546
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 46119039 times.
46119039 if((GameFlags & (GAMEFLAG_SCRIPTMENU_ACTIVE|GAMEFLAG_F6SCRIPT_ACTIVE))!=0)
4547 {
4548 FFCore.doScriptMenuDraws();
4549 return;
4550 }
4551
4552
2/2
✓ Branch 0 taken 31180939 times.
✓ Branch 1 taken 14938100 times.
46119039 if(runGeneric) FFCore.runGenericPassiveEngine(SCR_TIMING_PRE_DRAW);
4553
4554 46119039 clear_bitmap(framebuf);
4555 46119039 clear_clip_rect(framebuf);
4556
4557 46119039 int32_t cmby2=0;
4558
4559 // Draw some background layers
4560 46119039 clear_bitmap(scrollbuf);
4561
4562 46119039 auto nearby_screens = get_nearby_screens();
4563
4564 // Handle layer 2/3 possibly being background layers.
4565
1/2
✓ Branch 0 taken 46119039 times.
✗ Branch 1 not taken.
61795122 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4566 15676083 mapscr* base_scr = screen_handles[0].base_scr;
4567
2/2
✓ Branch 0 taken 15548802 times.
✓ Branch 1 taken 127281 times.
15676083 if (XOR(base_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
4568 127281 do_layer(scrollbuf, 0, screen_handles[2], offx, offy);
4569 15676083 });
4570
4571
2/2
✓ Branch 0 taken 127281 times.
✓ Branch 1 taken 45991758 times.
46119039 if (XOR(origin_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
4572 {
4573
1/2
✓ Branch 0 taken 127281 times.
✗ Branch 1 not taken.
127281 do_layer_primitives(scrollbuf, 2);
4574
1/2
✓ Branch 0 taken 127281 times.
✗ Branch 1 not taken.
127281 particles.draw(scrollbuf, true, 2);
4575 127281 }
4576
2/2
✓ Branch 0 taken 15539765 times.
✓ Branch 1 taken 30579274 times.
46119039 _do_current_ffc_layer(scrollbuf, -2);
4577
2/2
✓ Branch 0 taken 127281 times.
✓ Branch 1 taken 15412484 times.
15539765 if (XOR(origin_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
4578
1/2
✓ Branch 0 taken 127281 times.
✗ Branch 1 not taken.
127281 draw_msgstr(2, scrollbuf);
4579
4580
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
31215848 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4581 15676083 mapscr* base_scr = screen_handles[0].base_scr;
4582
2/2
✓ Branch 0 taken 15583424 times.
✓ Branch 1 taken 92659 times.
15676083 if (XOR(base_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
4583 92659 do_layer(scrollbuf, 0, screen_handles[3], offx, offy);
4584 15676083 });
4585
4586
2/2
✓ Branch 0 taken 92659 times.
✓ Branch 1 taken 15447106 times.
15539765 if (XOR(origin_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
4587 {
4588
1/2
✓ Branch 0 taken 92659 times.
✗ Branch 1 not taken.
92659 do_layer_primitives(scrollbuf, 3);
4589
1/2
✓ Branch 0 taken 92659 times.
✗ Branch 1 not taken.
92659 particles.draw(scrollbuf, true, 3);
4590 92659 }
4591
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 _do_current_ffc_layer(scrollbuf, -3);
4592
2/2
✓ Branch 0 taken 92659 times.
✓ Branch 1 taken 15447106 times.
15539765 if (XOR(origin_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
4593
1/2
✓ Branch 0 taken 92659 times.
✗ Branch 1 not taken.
92659 draw_msgstr(3, scrollbuf);
4594
4595 // Draw the main combo screens ("layer 0").
4596
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
31215848 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4597 15676083 mapscr* base_scr = screen_handles[0].base_scr;
4598
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15676083 times.
15676083 if (lenscheck(base_scr, 0))
4599 {
4600 15676083 putscr(base_scr, scrollbuf, offx, offy + playing_field_offset);
4601 15676083 }
4602 15676083 });
4603
4604
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15539765 times.
15539765 if (lenscheck(hero_scr, 0))
4605 {
4606
2/2
✓ Branch 0 taken 466049 times.
✓ Branch 1 taken 15073716 times.
15539765 if(!get_qr(qr_PUSHBLOCK_SPRITE_LAYER))
4607
3/4
✓ Branch 0 taken 466049 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4136 times.
✓ Branch 3 taken 461913 times.
470185 if(mblock2.draw(scrollbuf,0))
4608
1/2
✓ Branch 0 taken 4136 times.
✗ Branch 1 not taken.
4136 do_primitives(scrollbuf, SPLAYER_MOVINGBLOCK);
4609 15539765 }
4610
4611 // Lens hints, then primitives, then particles.
4612
6/10
✓ Branch 0 taken 15529736 times.
✓ Branch 1 taken 10029 times.
✓ Branch 2 taken 15529736 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 15529736 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 5876 times.
✓ Branch 9 taken 4153 times.
15539765 if((lensclk || (get_debug() && zc_getkey(KEY_L))) && !get_qr(qr_OLDLENSORDER))
4613 {
4614
1/2
✓ Branch 0 taken 5876 times.
✗ Branch 1 not taken.
5876 draw_lens_under(scrollbuf, false);
4615
1/2
✓ Branch 0 taken 5876 times.
✗ Branch 1 not taken.
5876 do_primitives(scrollbuf, SPLAYER_LENS_UNDER_1);
4616 5876 }
4617
4618
2/4
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15539765 times.
✗ Branch 3 not taken.
15539765 if(show_layers[0] && lenscheck(hero_scr,0))
4619
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 do_primitives(scrollbuf, 0);
4620
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 particles.draw(scrollbuf, true, 0);
4621
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 _do_current_ffc_layer(scrollbuf, 0);
4622
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 draw_msgstr(0, scrollbuf);
4623
4624
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 set_draw_screen_clip(scrollbuf);
4625
4626
2/2
✓ Branch 0 taken 15196506 times.
✓ Branch 1 taken 343259 times.
15539765 if(!(get_qr(qr_LAYER12UNDERCAVE)))
4627 {
4628
4/4
✓ Branch 0 taken 15194632 times.
✓ Branch 1 taken 1874 times.
✓ Branch 2 taken 53632 times.
✓ Branch 3 taken 15106248 times.
30356386 if(showhero &&
4629
4/6
✓ Branch 0 taken 15194632 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15159880 times.
✓ Branch 3 taken 34752 times.
✓ Branch 4 taken 15159880 times.
✗ Branch 5 not taken.
15194632 ((Hero.getAction()==climbcovertop)||(Hero.getAction()==climbcoverbottom)))
4630 {
4631
3/4
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 53632 times.
✓ Branch 3 taken 34752 times.
88384 if(Hero.getAction()==climbcovertop)
4632 {
4633 34752 cmby2=16;
4634 34752 }
4635
2/4
✓ Branch 0 taken 53632 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 53632 times.
53632 else if(Hero.getAction()==climbcoverbottom)
4636 {
4637 53632 cmby2=-16;
4638 53632 }
4639
4640
1/2
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
88384 decorations.draw2(scrollbuf,true);
4641
1/2
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
88384 Hero.draw(scrollbuf);
4642
1/2
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
88384 decorations.draw(scrollbuf,true);
4643
2/4
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 88384 times.
✗ Branch 3 not taken.
88384 int32_t ccx = (int32_t)Hero.getClimbCoverX();
4644
2/4
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 88384 times.
✗ Branch 3 not taken.
88384 int32_t ccy = (int32_t)Hero.getClimbCoverY();
4645
4646
3/6
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 88384 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 88384 times.
✗ Branch 5 not taken.
88384 overcombo(scrollbuf,ccx-viewport.x,ccy+cmby2+playing_field_offset-viewport.y,MAPCOMBO(ccx,ccy+cmby2),MAPCSET(ccx,ccy+cmby2));
4647
3/6
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 88384 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 88384 times.
✗ Branch 5 not taken.
88384 putcombo(scrollbuf,ccx-viewport.x,ccy+playing_field_offset-viewport.y,MAPCOMBO(ccx,ccy),MAPCSET(ccx,ccy));
4648
4649
4/6
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 88384 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15232 times.
✓ Branch 5 taken 73152 times.
88384 if(int32_t(Hero.getX())&15)
4650 {
4651
3/6
✓ Branch 0 taken 15232 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15232 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15232 times.
✗ Branch 5 not taken.
15232 overcombo(scrollbuf,ccx+16-viewport.x,ccy+cmby2+playing_field_offset-viewport.y,MAPCOMBO(ccx+16,ccy+cmby2),MAPCSET(ccx+16,ccy+cmby2));
4652
3/6
✓ Branch 0 taken 15232 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15232 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15232 times.
✗ Branch 5 not taken.
15232 putcombo(scrollbuf,ccx+16-viewport.x,ccy+playing_field_offset-viewport.y,MAPCOMBO(ccx+16,ccy),MAPCSET(ccx+16,ccy));
4653 15232 }
4654 88384 }
4655 15196506 }
4656
4657
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
31215848 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4658 15676083 do_layer(scrollbuf, 0, screen_handles[1], offx, offy); // LAYER 1
4659 15676083 });
4660
4661
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 do_layer_primitives(scrollbuf, 1);
4662
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 particles.draw(scrollbuf, true, 1);
4663
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 _do_current_ffc_layer(scrollbuf, 1);
4664
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 draw_msgstr(1, scrollbuf);
4665
4666 // Handle layer 2 NOT being used as background layers.
4667
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
31215848 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4668 15676083 mapscr* base_scr = screen_handles[0].base_scr;
4669
2/2
✓ Branch 0 taken 127281 times.
✓ Branch 1 taken 15548802 times.
15676083 if (!XOR(base_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
4670 15548802 do_layer(scrollbuf, 0, screen_handles[2], offx, offy);
4671 15676083 });
4672
4673
2/2
✓ Branch 0 taken 15412484 times.
✓ Branch 1 taken 127281 times.
15539765 if(!XOR(origin_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
4674 {
4675
1/2
✓ Branch 0 taken 15412484 times.
✗ Branch 1 not taken.
15412484 do_layer_primitives(scrollbuf, 2);
4676
1/2
✓ Branch 0 taken 15412484 times.
✗ Branch 1 not taken.
15412484 particles.draw(scrollbuf, true, 2);
4677 15412484 }
4678
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 _do_current_ffc_layer(scrollbuf, 2);
4679
2/2
✓ Branch 0 taken 15412484 times.
✓ Branch 1 taken 127281 times.
15539765 if(!XOR(origin_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
4680
1/2
✓ Branch 0 taken 15412484 times.
✗ Branch 1 not taken.
15412484 draw_msgstr(2, scrollbuf);
4681
4682
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 do_primitives(scrollbuf, SPLAYER_FFC_DRAW);
4683
4684
2/2
✓ Branch 0 taken 343259 times.
✓ Branch 1 taken 15196506 times.
15539765 if(get_qr(qr_LAYER12UNDERCAVE))
4685 {
4686
2/4
✓ Branch 0 taken 343259 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 343259 times.
686518 if(showhero &&
4687
3/6
✓ Branch 0 taken 343259 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 343259 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 343259 times.
✗ Branch 5 not taken.
343259 ((Hero.getAction()==climbcovertop)||(Hero.getAction()==climbcoverbottom)))
4688 {
4689 if(Hero.getAction()==climbcovertop)
4690 {
4691 cmby2=16;
4692 }
4693 else if(Hero.getAction()==climbcoverbottom)
4694 {
4695 cmby2=-16;
4696 }
4697
4698 decorations.draw2(scrollbuf,true);
4699 Hero.draw(scrollbuf);
4700 decorations.draw(scrollbuf,true);
4701 int32_t ccx = (int32_t)(Hero.getClimbCoverX());
4702 int32_t ccy = (int32_t)(Hero.getClimbCoverY());
4703
4704 overcombo(scrollbuf,ccx-viewport.x,ccy+cmby2+playing_field_offset-viewport.y,MAPCOMBO(ccx,ccy+cmby2),MAPCSET(ccx,ccy+cmby2));
4705 putcombo(scrollbuf,ccx-viewport.x,ccy+playing_field_offset-viewport.y,MAPCOMBO(ccx,ccy),MAPCSET(ccx,ccy));
4706
4707 if(int32_t(Hero.getX())&15)
4708 {
4709 overcombo(scrollbuf,ccx+16-viewport.x,ccy+cmby2+playing_field_offset-viewport.y,MAPCOMBO(ccx+16,ccy+cmby2),MAPCSET(ccx+16,ccy+cmby2));
4710 putcombo(scrollbuf,ccx+16-viewport.x,ccy+playing_field_offset-viewport.y,MAPCOMBO(ccx+16,ccy),MAPCSET(ccx+16,ccy));
4711 }
4712 }
4713 343259 }
4714
4715
2/2
✓ Branch 0 taken 466049 times.
✓ Branch 1 taken 15073716 times.
15539765 if (get_qr(qr_PUSHBLOCK_SPRITE_LAYER))
4716 {
4717
1/2
✓ Branch 0 taken 15073716 times.
✗ Branch 1 not taken.
30283750 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4718 15210034 do_layer(scrollbuf, -2, screen_handles[0], offx, offy); // push blocks!
4719
2/2
✓ Branch 0 taken 14478915 times.
✓ Branch 1 taken 731119 times.
15210034 if(get_qr(qr_PUSHBLOCK_LAYER_1_2))
4720 {
4721 731119 do_layer(scrollbuf, -2, screen_handles[1], offx, offy); // push blocks!
4722 731119 do_layer(scrollbuf, -2, screen_handles[2], offx, offy); // push blocks!
4723 731119 }
4724 15210034 });
4725
4726
1/2
✓ Branch 0 taken 15073716 times.
✗ Branch 1 not taken.
15073716 do_primitives(scrollbuf, SPLAYER_PUSHBLOCK);
4727 15073716 }
4728
4729 // Show walkflags cheat
4730
2/4
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 15539765 times.
15539765 if (show_walkflags || show_effectflags)
4731 {
4732 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4733 do_walkflags(screen_handles, offx, offy);
4734 do_effectflags(screen_handles[0].base_scr, offx, offy);
4735 });
4736
4737 do_walkflags(0, 0);
4738 }
4739
4740
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 putscrdoors(nearby_screens, scrollbuf, 0, playing_field_offset);
4741
4742 // Lens hints, doors etc.
4743
4/8
✓ Branch 0 taken 15529736 times.
✓ Branch 1 taken 10029 times.
✓ Branch 2 taken 15529736 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 15529736 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
15539765 if(lensclk || (get_debug() && zc_getkey(KEY_L)))
4744 {
4745
2/2
✓ Branch 0 taken 4153 times.
✓ Branch 1 taken 5876 times.
10029 if(get_qr(qr_OLDLENSORDER))
4746 {
4747
1/2
✓ Branch 0 taken 4153 times.
✗ Branch 1 not taken.
4153 draw_lens_under(scrollbuf, false);
4748
1/2
✓ Branch 0 taken 4153 times.
✗ Branch 1 not taken.
4153 do_primitives(scrollbuf, SPLAYER_LENS_UNDER_1);
4749 4153 }
4750
4751
1/2
✓ Branch 0 taken 10029 times.
✗ Branch 1 not taken.
10029 draw_lens_under(scrollbuf, true);
4752
1/2
✓ Branch 0 taken 10029 times.
✗ Branch 1 not taken.
10029 do_primitives(scrollbuf, SPLAYER_LENS_UNDER_2);
4753 10029 }
4754
4755 // Blit those layers onto framebuf
4756
4757
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 set_draw_screen_clip(framebuf);
4758
4759
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 blit(scrollbuf, framebuf, 0, 0, 0, 0, 256, 232);
4760
4761 // After this point, scrollbuf is no longer drawn to - so things like dosubscr have access to a "partially rendered" frame.
4762 // I think only used for COOLSCROLL==0? Seems like a silly feature...
4763
4764 // Draw the subscreen, without clipping
4765
2/2
✓ Branch 0 taken 9251384 times.
✓ Branch 1 taken 6288381 times.
15539765 if(!get_qr(qr_SUBSCREENOVERSPRITES))
4766 {
4767 9251384 bool dotime = false;
4768
4/6
✓ Branch 0 taken 9251384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3412853 times.
✓ Branch 3 taken 5838531 times.
✓ Branch 4 taken 3412853 times.
✗ Branch 5 not taken.
9251384 if (replay_version_check(22)) dotime = game->should_show_time();
4769
1/2
✓ Branch 0 taken 9251384 times.
✗ Branch 1 not taken.
9251384 put_passive_subscr(framebuf, 0, 0, dotime, sspUP);
4770 9251384 }
4771
4772 // Draw some sprites onto framebuf
4773
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 set_clip_rect(framebuf,0,0,256,232);
4774
4775
2/2
✓ Branch 0 taken 99496 times.
✓ Branch 1 taken 15440269 times.
15539765 if(!(pricesdisplaybuf->clip))
4776 {
4777
1/2
✓ Branch 0 taken 99496 times.
✗ Branch 1 not taken.
99496 masked_blit(pricesdisplaybuf,framebuf,0,0,0,playing_field_offset,256,176);
4778 99496 }
4779
4780
5/6
✓ Branch 0 taken 15494139 times.
✓ Branch 1 taken 45626 times.
✓ Branch 2 taken 6328 times.
✓ Branch 3 taken 15487811 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 6328 times.
15539765 if (!is_extended_height_mode() && is_in_scrolling_region() && !get_qr(qr_SUBSCREENOVERSPRITES))
4781 add_clip_rect(framebuf, 0, playing_field_offset, framebuf->w, framebuf->h);
4782
4783
8/10
✓ Branch 0 taken 15537891 times.
✓ Branch 1 taken 1874 times.
✓ Branch 2 taken 15537891 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15503139 times.
✓ Branch 5 taken 34752 times.
✓ Branch 6 taken 15503139 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 15449507 times.
✓ Branch 9 taken 53632 times.
15539765 if(showhero && ((Hero.getAction()!=climbcovertop)&&(Hero.getAction()!=climbcoverbottom)))
4784 {
4785
1/2
✓ Branch 0 taken 15449507 times.
✗ Branch 1 not taken.
15449507 Hero.draw_under(framebuf);
4786
4787
3/4
✓ Branch 0 taken 15449507 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 141385 times.
✓ Branch 3 taken 15308122 times.
15449507 if(Hero.isSwimming())
4788 {
4789
1/2
✓ Branch 0 taken 141385 times.
✗ Branch 1 not taken.
141385 decorations.draw2(framebuf,true);
4790
1/2
✓ Branch 0 taken 141385 times.
✗ Branch 1 not taken.
141385 Hero.draw(framebuf);
4791
1/2
✓ Branch 0 taken 141385 times.
✗ Branch 1 not taken.
141385 decorations.draw(framebuf,true);
4792 141385 }
4793 15449507 }
4794
4795
2/2
✓ Branch 0 taken 26095 times.
✓ Branch 1 taken 15513670 times.
15539765 if(drawguys)
4796 {
4797
4/4
✓ Branch 0 taken 1982674 times.
✓ Branch 1 taken 13530996 times.
✓ Branch 2 taken 991089 times.
✓ Branch 3 taken 991585 times.
15513670 if(get_qr(qr_NOFLICKER) || (frame&1))
4798 {
4799 // Just clips sprites if in a repeating, smooth maze.
4800
2/2
✓ Branch 0 taken 14512871 times.
✓ Branch 1 taken 9214 times.
14522085 bool do_clip = maze_state.active && maze_state.loopy;
4801
4802
3/4
✓ Branch 0 taken 23627227 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9105142 times.
✓ Branch 3 taken 14522085 times.
23627227 for(int32_t i=0; i<Ewpns.Count(); i++)
4803 {
4804
3/4
✓ Branch 0 taken 9105142 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 197943 times.
✓ Branch 3 taken 8907199 times.
9105142 if(((weapon *)Ewpns.spr(i))->behind)
4805
2/4
✓ Branch 0 taken 197943 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 197943 times.
✗ Branch 3 not taken.
197943 Ewpns.spr(i)->draw(framebuf);
4806 9105142 }
4807
1/2
✓ Branch 0 taken 14522085 times.
✗ Branch 1 not taken.
14522085 do_primitives(framebuf, SPLAYER_EWEAP_BEHIND_DRAW);
4808
4809
3/4
✓ Branch 0 taken 19197181 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4675096 times.
✓ Branch 3 taken 14522085 times.
19197181 for(int32_t i=0; i<Lwpns.Count(); i++)
4810 {
4811
3/4
✓ Branch 0 taken 4675096 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3205 times.
✓ Branch 3 taken 4671891 times.
4675096 if(((weapon *)Lwpns.spr(i))->behind)
4812
2/4
✓ Branch 0 taken 3205 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3205 times.
✗ Branch 3 not taken.
3205 Lwpns.spr(i)->draw(framebuf);
4813 4675096 }
4814
1/2
✓ Branch 0 taken 14522085 times.
✗ Branch 1 not taken.
14522085 do_primitives(framebuf, SPLAYER_LWEAP_BEHIND_DRAW);
4815
4816
6/6
✓ Branch 0 taken 9785221 times.
✓ Branch 1 taken 4736864 times.
✓ Branch 2 taken 1348300 times.
✓ Branch 3 taken 8436921 times.
✓ Branch 4 taken 674011 times.
✓ Branch 5 taken 674289 times.
14522085 if(get_qr(qr_SHADOWS)&&(!get_qr(qr_SHADOWSFLICKER)||frame&1))
4817 {
4818
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 9107274 times.
9110932 if (do_clip)
4819
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 guys.drawshadow_smooth_maze(framebuf,get_qr(qr_TRANSSHADOWS)!=0);
4820 else
4821
1/2
✓ Branch 0 taken 9107274 times.
✗ Branch 1 not taken.
9107274 guys.drawshadow(framebuf,get_qr(qr_TRANSSHADOWS)!=0,true);
4822 9110932 }
4823
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 14518427 times.
14522085 if (do_clip)
4824
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 guys.draw_smooth_maze(framebuf);
4825 else
4826
1/2
✓ Branch 0 taken 14518427 times.
✗ Branch 1 not taken.
14518427 guys.draw(framebuf,true);
4827
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 14518427 times.
14522085 if (do_clip)
4828 {
4829 3658 int maze_screen = maze_state.scr->screen;
4830
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 auto [sx, sy] = translate_screen_coordinates_to_world(maze_screen);
4831
5/10
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3658 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3658 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 3658 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 3658 times.
✗ Branch 9 not taken.
18290 set_clip_rect(framebuf, sx - viewport.x, sy - viewport.y, sx + 256 - viewport.x, sy + 176 - viewport.y);
4832 3658 }
4833
1/2
✓ Branch 0 taken 14522085 times.
✗ Branch 1 not taken.
14522085 do_primitives(framebuf, SPLAYER_NPC_DRAW);
4834
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 14518427 times.
14522085 if (do_clip)
4835
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 clear_clip_rect(framebuf);
4836
4837
1/2
✓ Branch 0 taken 14522085 times.
✗ Branch 1 not taken.
14522085 chainlinks.draw(framebuf,true);
4838
1/2
✓ Branch 0 taken 14522085 times.
✗ Branch 1 not taken.
14522085 do_primitives(framebuf, SPLAYER_CHAINLINK_DRAW);
4839 //Lwpns.draw(framebuf,true);
4840
4841
3/4
✓ Branch 0 taken 23627227 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9105142 times.
✓ Branch 3 taken 14522085 times.
23627227 for(int32_t i=0; i<Ewpns.Count(); i++)
4842 {
4843
3/4
✓ Branch 0 taken 9105142 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8907199 times.
✓ Branch 3 taken 197943 times.
9105142 if(!((weapon *)Ewpns.spr(i))->behind)
4844
2/4
✓ Branch 0 taken 8907199 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8907199 times.
✗ Branch 3 not taken.
8907199 Ewpns.spr(i)->draw(framebuf);
4845 9105142 }
4846
1/2
✓ Branch 0 taken 14522085 times.
✗ Branch 1 not taken.
14522085 do_primitives(framebuf, SPLAYER_EWEAP_FRONT_DRAW);
4847
4848
3/4
✓ Branch 0 taken 19197181 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4675096 times.
✓ Branch 3 taken 14522085 times.
19197181 for(int32_t i=0; i<Lwpns.Count(); i++)
4849 {
4850
3/4
✓ Branch 0 taken 4675096 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4671891 times.
✓ Branch 3 taken 3205 times.
4675096 if(!((weapon *)Lwpns.spr(i))->behind)
4851
2/4
✓ Branch 0 taken 4671891 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4671891 times.
✗ Branch 3 not taken.
4671891 Lwpns.spr(i)->draw(framebuf);
4852 4675096 }
4853
1/2
✓ Branch 0 taken 14522085 times.
✗ Branch 1 not taken.
14522085 do_primitives(framebuf, SPLAYER_LWEAP_FRONT_DRAW);
4854
4855
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 14518427 times.
14522085 if (do_clip)
4856
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 items.draw_smooth_maze(framebuf);
4857 else
4858
1/2
✓ Branch 0 taken 14518427 times.
✗ Branch 1 not taken.
14518427 items.draw(framebuf,true);
4859
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 14518427 times.
14522085 if (do_clip)
4860 {
4861 3658 int maze_screen = maze_state.scr->screen;
4862
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 auto [sx, sy] = translate_screen_coordinates_to_world(maze_screen);
4863
5/10
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3658 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3658 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 3658 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 3658 times.
✗ Branch 9 not taken.
18290 set_clip_rect(framebuf, sx - viewport.x, sy - viewport.y, sx + 256 - viewport.x, sy + 176 - viewport.y);
4864 3658 }
4865
1/2
✓ Branch 0 taken 14522085 times.
✗ Branch 1 not taken.
14522085 do_primitives(framebuf, SPLAYER_ITEMSPRITE_DRAW);
4866
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 14518427 times.
14522085 if (do_clip)
4867
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 clear_clip_rect(framebuf);
4868 14522085 }
4869 else
4870 {
4871
3/4
✓ Branch 0 taken 1496957 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 505372 times.
✓ Branch 3 taken 991585 times.
1496957 for(int32_t i=0; i<Ewpns.Count(); i++)
4872 {
4873
3/4
✓ Branch 0 taken 505372 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8645 times.
✓ Branch 3 taken 496727 times.
505372 if(((weapon *)Ewpns.spr(i))->behind)
4874
2/4
✓ Branch 0 taken 8645 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8645 times.
✗ Branch 3 not taken.
8645 Ewpns.spr(i)->draw(framebuf);
4875 505372 }
4876
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 do_primitives(framebuf, SPLAYER_EWEAP_BEHIND_DRAW);
4877
4878
3/4
✓ Branch 0 taken 1222731 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 231146 times.
✓ Branch 3 taken 991585 times.
1222731 for(int32_t i=0; i<Lwpns.Count(); i++)
4879 {
4880
2/4
✓ Branch 0 taken 231146 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 231146 times.
231146 if(((weapon *)Lwpns.spr(i))->behind)
4881 Lwpns.spr(i)->draw(framebuf);
4882 231146 }
4883
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 do_primitives(framebuf, SPLAYER_LWEAP_BEHIND_DRAW);
4884
4885
3/4
✓ Branch 0 taken 228620 times.
✓ Branch 1 taken 762965 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 228620 times.
991585 if(get_qr(qr_SHADOWS)&&(!get_qr(qr_SHADOWSFLICKER)||frame&1))
4886 {
4887
1/2
✓ Branch 0 taken 228620 times.
✗ Branch 1 not taken.
228620 guys.drawshadow(framebuf,get_qr(qr_TRANSSHADOWS)!=0,true);
4888 228620 }
4889
4890
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 items.draw(framebuf,false);
4891
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 do_primitives(framebuf, SPLAYER_ITEMSPRITE_DRAW);
4892
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 chainlinks.draw(framebuf,false);
4893
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 do_primitives(framebuf, SPLAYER_CHAINLINK_DRAW);
4894 //Lwpns.draw(framebuf,false);
4895
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 guys.draw(framebuf,false);
4896
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 do_primitives(framebuf, SPLAYER_NPC_DRAW);
4897
4898
3/4
✓ Branch 0 taken 1496957 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 505372 times.
✓ Branch 3 taken 991585 times.
1496957 for(int32_t i=0; i<Ewpns.Count(); i++)
4899 {
4900
3/4
✓ Branch 0 taken 505372 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 496727 times.
✓ Branch 3 taken 8645 times.
505372 if(!((weapon *)Ewpns.spr(i))->behind)
4901 {
4902
2/4
✓ Branch 0 taken 496727 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 496727 times.
✗ Branch 3 not taken.
496727 Ewpns.spr(i)->draw(framebuf);
4903 496727 }
4904 505372 }
4905
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 do_primitives(framebuf, SPLAYER_EWEAP_FRONT_DRAW);
4906
4907
3/4
✓ Branch 0 taken 1222731 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 231146 times.
✓ Branch 3 taken 991585 times.
1222731 for(int32_t i=0; i<Lwpns.Count(); i++)
4908 {
4909
2/4
✓ Branch 0 taken 231146 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 231146 times.
✗ Branch 3 not taken.
231146 if(!((weapon *)Lwpns.spr(i))->behind)
4910 {
4911
2/4
✓ Branch 0 taken 231146 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 231146 times.
✗ Branch 3 not taken.
231146 Lwpns.spr(i)->draw(framebuf);
4912 231146 }
4913 231146 }
4914
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 do_primitives(framebuf, SPLAYER_LWEAP_FRONT_DRAW);
4915 }
4916
4917
1/2
✓ Branch 0 taken 15513670 times.
✗ Branch 1 not taken.
15513670 guys.draw2(framebuf,true);
4918 15513670 }
4919
4920
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15539765 times.
15539765 if(mirror_portal.destdmap > -1)
4921 mirror_portal.draw(framebuf);
4922
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 portals.draw(framebuf,true);
4923
4924
8/10
✓ Branch 0 taken 15537891 times.
✓ Branch 1 taken 1874 times.
✓ Branch 2 taken 15537891 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15503139 times.
✓ Branch 5 taken 34752 times.
✓ Branch 6 taken 15503139 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 15449507 times.
✓ Branch 9 taken 53632 times.
15539765 if(showhero && ((Hero.getAction()!=climbcovertop)&& (Hero.getAction()!=climbcoverbottom)))
4925 {
4926
2/2
✓ Branch 0 taken 14989874 times.
✓ Branch 1 taken 459633 times.
15449507 if(get_qr(qr_PUSHBLOCK_SPRITE_LAYER))
4927 {
4928
1/2
✓ Branch 0 taken 14989874 times.
✗ Branch 1 not taken.
14989874 mblock2.draw(framebuf,-1);
4929
1/2
✓ Branch 0 taken 14989874 times.
✗ Branch 1 not taken.
14989874 do_primitives(framebuf, SPLAYER_MOVINGBLOCK);
4930 14989874 }
4931
3/4
✓ Branch 0 taken 15449507 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15308122 times.
✓ Branch 3 taken 141385 times.
15449507 if(!Hero.isSwimming())
4932 {
4933
8/12
✓ Branch 0 taken 15308122 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15308122 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15288952 times.
✓ Branch 5 taken 19170 times.
✓ Branch 6 taken 15288952 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 15288952 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 1370 times.
✓ Branch 11 taken 15306752 times.
15308122 if((Hero.getZ()>0 || Hero.getFakeZ()>0) &&(!get_qr(qr_SHADOWSFLICKER)||frame&1))
4934 {
4935
2/2
✓ Branch 0 taken 18485 times.
✓ Branch 1 taken 15289637 times.
15308122 Hero.drawshadow(framebuf,get_qr(qr_TRANSSHADOWS)!=0);
4936 18485 }
4937
4938
6/8
✓ Branch 0 taken 15308122 times.
✓ Branch 1 taken 15289637 times.
✓ Branch 2 taken 15308122 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15308122 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 15294058 times.
✓ Branch 7 taken 14064 times.
18485 if(Hero.getZ() <= (zfix)zinit.jump_hero_layer_threshold)
4939 {
4940
1/2
✓ Branch 0 taken 15294058 times.
✗ Branch 1 not taken.
15294058 decorations.draw2(framebuf,true);
4941
1/2
✓ Branch 0 taken 15294058 times.
✗ Branch 1 not taken.
15294058 Hero.draw(framebuf);
4942
1/2
✓ Branch 0 taken 15294058 times.
✗ Branch 1 not taken.
15294058 decorations.draw(framebuf,true);
4943 15294058 }
4944 15308122 }
4945 15449507 }
4946
4947
3/4
✓ Branch 0 taken 54880218 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 39340453 times.
✓ Branch 3 taken 15539765 times.
54880218 for(int32_t i=0; i<guys.Count(); i++)
4948 {
4949
3/4
✓ Branch 0 taken 39340453 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15945464 times.
✓ Branch 3 taken 23394989 times.
39340453 if(((enemy*)guys.spr(i))->type == eeWALK)
4950 {
4951
3/4
✓ Branch 0 taken 15945464 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7295 times.
✓ Branch 3 taken 15938169 times.
15945464 if(((eStalfos*)guys.spr(i))->hashero)
4952 {
4953
2/4
✓ Branch 0 taken 7295 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7295 times.
✗ Branch 3 not taken.
7295 guys.spr(i)->draw(framebuf);
4954 7295 }
4955 15945464 }
4956
4957
3/4
✓ Branch 0 taken 39340453 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 507162 times.
✓ Branch 3 taken 38833291 times.
39340453 if(((enemy*)guys.spr(i))->type == eeWALLM)
4958 {
4959
3/4
✓ Branch 0 taken 507162 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1329 times.
✓ Branch 3 taken 505833 times.
507162 if(((eWallM*)guys.spr(i))->hashero)
4960 {
4961
2/4
✓ Branch 0 taken 1329 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1329 times.
✗ Branch 3 not taken.
1329 guys.spr(i)->draw(framebuf);
4962 1329 }
4963 507162 }
4964
4965
11/20
✓ Branch 0 taken 39340453 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 39340453 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 39340453 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 39340453 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 39340453 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 39340453 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 39340453 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 39340453 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 39340453 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 1342694 times.
✓ Branch 19 taken 37997759 times.
39340453 if(guys.spr(i)->z+guys.spr(i)->fakez > Hero.getZ()+Hero.getFakeZ())
4966 {
4967 //Jumping enemies in front of Hero.
4968
2/4
✓ Branch 0 taken 1342694 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1342694 times.
✗ Branch 3 not taken.
1342694 guys.spr(i)->draw(framebuf);
4969 1342694 }
4970
1/2
✓ Branch 0 taken 39340453 times.
✗ Branch 1 not taken.
39340453 do_primitives(framebuf, SPLAYER_NPC_ABOVEPLAYER_DRAW);
4971 39340453 }
4972
4973 // Draw some layers onto framebuf
4974
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 set_draw_screen_clip(framebuf);
4975
5/6
✓ Branch 0 taken 15494139 times.
✓ Branch 1 taken 45626 times.
✓ Branch 2 taken 6328 times.
✓ Branch 3 taken 15487811 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 6328 times.
15539765 if (!is_extended_height_mode() && is_in_scrolling_region() && !get_qr(qr_SUBSCREENOVERSPRITES))
4976 add_clip_rect(framebuf, 0, playing_field_offset, framebuf->w, framebuf->h);
4977
4978 // Handle layer 3 NOT being used as background layers.
4979
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
31215848 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4980 15676083 mapscr* base_scr = screen_handles[0].base_scr;
4981
2/2
✓ Branch 0 taken 92659 times.
✓ Branch 1 taken 15583424 times.
15676083 if (!XOR(base_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
4982 15583424 do_layer(framebuf, 0, screen_handles[3], offx, offy);
4983 15676083 });
4984
4985
2/2
✓ Branch 0 taken 15447106 times.
✓ Branch 1 taken 92659 times.
15539765 if(!XOR(origin_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
4986 {
4987
1/2
✓ Branch 0 taken 15447106 times.
✗ Branch 1 not taken.
15447106 do_layer_primitives(framebuf, 3);
4988
1/2
✓ Branch 0 taken 15447106 times.
✗ Branch 1 not taken.
15447106 particles.draw(framebuf, true, 3);
4989 15447106 }
4990
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 _do_current_ffc_layer(framebuf, 3);
4991
2/2
✓ Branch 0 taken 15447106 times.
✓ Branch 1 taken 92659 times.
15539765 if(!XOR(origin_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
4992
1/2
✓ Branch 0 taken 15447106 times.
✗ Branch 1 not taken.
15447106 draw_msgstr(3);
4993
4994
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
31215848 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4995 15676083 do_layer(framebuf, 0, screen_handles[4], offx, offy);
4996 15676083 });
4997
4998
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 do_layer_primitives(framebuf, 4);
4999
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 particles.draw(framebuf, true, 4);
5000
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 _do_current_ffc_layer(framebuf, 4);
5001
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 draw_msgstr(4);
5002
5003
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
31215848 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
5004 15676083 do_layer(framebuf, -1, screen_handles[0], offx, offy);
5005
2/2
✓ Branch 0 taken 14400195 times.
✓ Branch 1 taken 1275888 times.
15676083 if (get_qr(qr_OVERHEAD_COMBOS_L1_L2))
5006 {
5007 1275888 do_layer(framebuf, -1, screen_handles[1], offx, offy);
5008 1275888 do_layer(framebuf, -1, screen_handles[2], offx, offy);
5009 1275888 }
5010 15676083 });
5011
5012
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 do_primitives(framebuf, SPLAYER_OVERHEAD_CMB);
5013
5014 // Draw some flying sprites onto framebuf
5015
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 clear_clip_rect(framebuf);
5016
5/6
✓ Branch 0 taken 15494139 times.
✓ Branch 1 taken 45626 times.
✓ Branch 2 taken 6328 times.
✓ Branch 3 taken 15487811 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 6328 times.
15539765 if (!is_extended_height_mode() && is_in_scrolling_region() && !get_qr(qr_SUBSCREENOVERSPRITES))
5017 add_clip_rect(framebuf, 0, playing_field_offset, framebuf->w, framebuf->h);
5018
5019 //Jumping Hero and jumping enemies are drawn on this layer.
5020
5/8
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15539765 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15539765 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 14064 times.
✓ Branch 7 taken 15525701 times.
15539765 if(Hero.getZ() > (zfix)zinit.jump_hero_layer_threshold)
5021 {
5022
1/2
✓ Branch 0 taken 14064 times.
✗ Branch 1 not taken.
14064 decorations.draw2(framebuf,false);
5023
1/2
✓ Branch 0 taken 14064 times.
✗ Branch 1 not taken.
14064 Hero.draw(framebuf);
5024
1/2
✓ Branch 0 taken 14064 times.
✗ Branch 1 not taken.
14064 chainlinks.draw(framebuf,true);
5025
1/2
✓ Branch 0 taken 14064 times.
✗ Branch 1 not taken.
14064 do_primitives(framebuf, SPLAYER_CHAINLINK_DRAW);
5026
5027
3/4
✓ Branch 0 taken 16806 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2742 times.
✓ Branch 3 taken 14064 times.
16806 for(int32_t i=0; i<Lwpns.Count(); i++)
5028 {
5029
9/16
✓ Branch 0 taken 2742 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2742 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2742 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 2742 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 2742 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 2742 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 2742 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 239 times.
✓ Branch 15 taken 2503 times.
2742 if(Lwpns.spr(i)->z+Lwpns.spr(i)->fakez > (zfix)zinit.jump_hero_layer_threshold)
5030 {
5031
2/4
✓ Branch 0 taken 239 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 239 times.
✗ Branch 3 not taken.
239 Lwpns.spr(i)->draw(framebuf);
5032 239 }
5033 2742 }
5034
1/2
✓ Branch 0 taken 14064 times.
✗ Branch 1 not taken.
14064 do_primitives(framebuf, SPLAYER_LWEAP_ABOVE_DRAW);
5035
5036
1/2
✓ Branch 0 taken 14064 times.
✗ Branch 1 not taken.
14064 decorations.draw(framebuf,false);
5037 14064 }
5038
5039
5/6
✓ Branch 0 taken 3288981 times.
✓ Branch 1 taken 12250784 times.
✓ Branch 2 taken 44334375 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 32083591 times.
✓ Branch 5 taken 12250784 times.
47623356 if(!get_qr(qr_ENEMIESZAXIS)) for(int32_t i=0; i<guys.Count(); i++)
5040 {
5041
13/22
✓ Branch 0 taken 32083591 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 32083591 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 27177493 times.
✓ Branch 5 taken 4906098 times.
✓ Branch 6 taken 27177493 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 27177493 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 27177493 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 27177493 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 27177493 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 27177493 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 27177493 times.
✗ Branch 19 not taken.
✓ Branch 20 taken 6568 times.
✓ Branch 21 taken 27170925 times.
32083591 if((isflier(guys.spr(i)->id)) || (guys.spr(i)->z+guys.spr(i)->fakez) > (zfix)zinit.jump_hero_layer_threshold)
5042 {
5043
2/4
✓ Branch 0 taken 4912666 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4912666 times.
✗ Branch 3 not taken.
4912666 guys.spr(i)->draw(framebuf);
5044 4912666 }
5045 44334375 }
5046 else
5047 {
5048
3/4
✓ Branch 0 taken 10545843 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7256862 times.
✓ Branch 3 taken 3288981 times.
10545843 for(int32_t i=0; i<guys.Count(); i++)
5049 {
5050
13/22
✓ Branch 0 taken 7256862 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7256862 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 6081157 times.
✓ Branch 5 taken 1175705 times.
✓ Branch 6 taken 6081157 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 6081157 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 6081157 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 5594346 times.
✓ Branch 13 taken 486811 times.
✓ Branch 14 taken 5594346 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 5594346 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 5594346 times.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✓ Branch 21 taken 5594346 times.
7256862 if((isflier(guys.spr(i)->id)) || guys.spr(i)->z > 0 || guys.spr(i)->fakez > 0)
5051 {
5052
2/4
✓ Branch 0 taken 1662516 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1662516 times.
✗ Branch 3 not taken.
1662516 guys.spr(i)->draw(framebuf);
5053 1662516 }
5054 7256862 }
5055 }
5056
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 do_primitives(framebuf, SPLAYER_NPC_AIRBORNE_DRAW);
5057
5058 // Draw the Moving Fairy above layer 3
5059
3/4
✓ Branch 0 taken 18684859 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3145094 times.
✓ Branch 3 taken 15539765 times.
18684859 for(int32_t i=0; i<items.Count(); i++)
5060
6/8
✓ Branch 0 taken 3145094 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 69867 times.
✓ Branch 3 taken 3075227 times.
✓ Branch 4 taken 69867 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 60153 times.
✓ Branch 7 taken 9714 times.
3205247 if(itemsbuf[items.spr(i)->id].type == itype_fairy && itemsbuf[items.spr(i)->id].misc3)
5061
2/4
✓ Branch 0 taken 60153 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 60153 times.
✗ Branch 3 not taken.
60153 items.spr(i)->draw(framebuf);
5062
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 do_primitives(framebuf, SPLAYER_FAIRYITEM_DRAW);
5063
5064 // Draw some layers onto framebuf
5065
5066
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 set_draw_screen_clip(framebuf);
5067
5068
2/2
✓ Branch 0 taken 15525413 times.
✓ Branch 1 taken 14352 times.
15539765 if (lightbeam_present)
5069 {
5070 14352 color_map = &trans_table2;
5071
2/2
✓ Branch 0 taken 13114 times.
✓ Branch 1 taken 1238 times.
14352 if(get_qr(qr_LIGHTBEAM_TRANSPARENT))
5072
1/2
✓ Branch 0 taken 13114 times.
✗ Branch 1 not taken.
13114 draw_trans_sprite(framebuf, lightbeam_bmp, 0, playing_field_offset);
5073 else
5074
1/2
✓ Branch 0 taken 1238 times.
✗ Branch 1 not taken.
1238 masked_blit(lightbeam_bmp, framebuf, 0, 0, 0, playing_field_offset, 256, 176);
5075 14352 color_map = &trans_table;
5076 14352 }
5077
5078
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
31215848 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
5079 15676083 do_layer(framebuf, 0, screen_handles[5], offx, offy);
5080 15676083 });
5081
5082
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 do_layer_primitives(framebuf, 5);
5083
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 particles.draw(framebuf, true, 5);
5084
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 _do_current_ffc_layer(framebuf, 5);
5085
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 draw_msgstr(5);
5086
5087
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 _do_current_ffc_layer(framebuf, -1); // 'overhead' freeform combos
5088
5089
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 do_primitives(framebuf, SPLAYER_OVERHEAD_FFC);
5090
5091
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
31215848 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
5092 15676083 do_layer(framebuf, 0, screen_handles[6], offx, offy);
5093 15676083 });
5094
5095
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 do_layer_primitives(framebuf, 6);
5096
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 particles.draw(framebuf, true, 6);
5097
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 _do_current_ffc_layer(framebuf, 6);
5098
5099 15539765 bool any_dark = false;
5100
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
31215848 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
5101 15676083 mapscr* base_scr = screen_handles[0].scr;
5102 15676083 any_dark |= is_dark(base_scr);
5103 15676083 });
5104
5105 // Handle low drawn darkness
5106
4/4
✓ Branch 0 taken 1269552 times.
✓ Branch 1 taken 14270213 times.
✓ Branch 2 taken 1025781 times.
✓ Branch 3 taken 243771 times.
15539765 if(get_qr(qr_NEW_DARKROOM) && any_dark)
5107 {
5108
1/2
✓ Branch 0 taken 243771 times.
✗ Branch 1 not taken.
493776 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
5109 250005 mapscr* base_scr = screen_handles[0].scr;
5110 250005 calc_darkroom_combos(base_scr, offx, offy + playing_field_offset);
5111 250005 calc_darkroom_ffcs(base_scr, 0, playing_field_offset);
5112 250005 });
5113
1/2
✓ Branch 0 taken 243771 times.
✗ Branch 1 not taken.
243771 if(showhero)
5114
1/2
✓ Branch 0 taken 243771 times.
✗ Branch 1 not taken.
243771 Hero.calc_darkroom_hero(0, -playing_field_offset);
5115
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 243771 times.
493776 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
5116 250005 mapscr* base_scr = screen_handles[0].scr;
5117
2/2
✓ Branch 0 taken 245275 times.
✓ Branch 1 taken 4730 times.
250005 if (!is_dark(base_scr))
5118 {
5119 4730 offy += playing_field_offset;
5120 4730 rectfill(darkscr_bmp, offx - viewport.x, offy - viewport.y, offx - viewport.x + 256 - 1, offy - viewport.y + 176 - 1, 0);
5121 4730 rectfill(darkscr_bmp_trans, offx - viewport.x, offy - viewport.y, offx - viewport.x + 256 - 1, offy - viewport.y + 176 - 1, 0);
5122 4730 }
5123 250005 });
5124 243771 }
5125
5126 //Darkroom if under the subscreen
5127
6/6
✓ Branch 0 taken 1269552 times.
✓ Branch 1 taken 14270213 times.
✓ Branch 2 taken 823284 times.
✓ Branch 3 taken 446268 times.
✓ Branch 4 taken 231780 times.
✓ Branch 5 taken 591504 times.
15539765 if(get_qr(qr_NEW_DARKROOM) && get_qr(qr_NEWDARK_L6) && any_dark)
5128 {
5129
1/2
✓ Branch 0 taken 231780 times.
✗ Branch 1 not taken.
231780 do_primitives(framebuf, SPLAYER_DARKROOM_UNDER);
5130
1/2
✓ Branch 0 taken 231780 times.
✗ Branch 1 not taken.
231780 set_clip_rect(framebuf, 0, playing_field_offset, framebuf->w, framebuf->h);
5131
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 231780 times.
231780 if(hero_scr->flags9 & fDARK_DITHER) //dither the entire bitmap
5132 {
5133 ditherblit(darkscr_bmp,darkscr_bmp,0,game->get_dither_type(),game->get_dither_arg());
5134 ditherblit(darkscr_bmp_trans,darkscr_bmp_trans,0,game->get_dither_type(),game->get_dither_arg());
5135 }
5136
5137 231780 color_map = &trans_table2;
5138
2/2
✓ Branch 0 taken 144 times.
✓ Branch 1 taken 231636 times.
231780 if(hero_scr->flags9 & fDARK_TRANS) //draw the dark as transparent
5139 {
5140
1/2
✓ Branch 0 taken 144 times.
✗ Branch 1 not taken.
144 draw_trans_sprite(framebuf, darkscr_bmp, 0, 0);
5141
1/2
✓ Branch 0 taken 144 times.
✗ Branch 1 not taken.
144 if(get_qr(qr_NEWDARK_TRANS_STACKING))
5142
1/2
✓ Branch 0 taken 144 times.
✗ Branch 1 not taken.
144 draw_trans_sprite(framebuf, darkscr_bmp_trans, 0, 0);
5143 144 }
5144 else
5145 {
5146
1/2
✓ Branch 0 taken 231636 times.
✗ Branch 1 not taken.
231636 masked_blit(darkscr_bmp, framebuf, 0, 0, 0, 0, framebuf->w, framebuf->h);
5147
1/2
✓ Branch 0 taken 231636 times.
✗ Branch 1 not taken.
231636 draw_trans_sprite(framebuf, darkscr_bmp_trans, 0, 0);
5148 }
5149 231780 color_map = &trans_table;
5150
5151
1/2
✓ Branch 0 taken 231780 times.
✗ Branch 1 not taken.
231780 set_clip_rect(framebuf, 0, 0, framebuf->w, framebuf->h);
5152
1/2
✓ Branch 0 taken 231780 times.
✗ Branch 1 not taken.
231780 do_primitives(framebuf, SPLAYER_DARKROOM_OVER);
5153 231780 }
5154
5155
3/6
✓ Branch 0 taken 45626 times.
✓ Branch 1 taken 15494139 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 45626 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
15539765 if (is_extended_height_mode() && lensclk && !FFCore.system_suspend[susptLENS])
5156 {
5157 draw_lens_over();
5158 --lensclk;
5159 }
5160
5161 // Draw some text on framebuf
5162
5163
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 set_clip_rect(framebuf,0,0,256,232);
5164
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 if(!get_qr(qr_LAYER6_STRINGS_OVER_SUBSCREEN))
5165
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 draw_msgstr(6);
5166
5167 // Draw the subscreen, without clipping
5168
2/2
✓ Branch 0 taken 6288381 times.
✓ Branch 1 taken 9251384 times.
15539765 if(get_qr(qr_SUBSCREENOVERSPRITES))
5169 {
5170
2/4
✓ Branch 0 taken 6288381 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6288381 times.
✗ Branch 3 not taken.
6288381 put_passive_subscr(framebuf, 0, 0, game->should_show_time(), sspUP);
5171
5172 // Draw primitives over subscren
5173
1/2
✓ Branch 0 taken 6288381 times.
✗ Branch 1 not taken.
6288381 do_primitives(framebuf, 7); //Layer '7' appears above subscreen if quest rule is set
5174 6288381 }
5175
5176
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15539765 times.
15539765 if(get_qr(qr_LAYER6_STRINGS_OVER_SUBSCREEN))
5177 draw_msgstr(6);
5178
5179 // Handle high-drawn darkness
5180
6/6
✓ Branch 0 taken 1269552 times.
✓ Branch 1 taken 14270213 times.
✓ Branch 2 taken 446268 times.
✓ Branch 3 taken 823284 times.
✓ Branch 4 taken 11991 times.
✓ Branch 5 taken 434277 times.
15539765 if(get_qr(qr_NEW_DARKROOM) && !get_qr(qr_NEWDARK_L6) && any_dark)
5181 {
5182
1/2
✓ Branch 0 taken 11991 times.
✗ Branch 1 not taken.
11991 do_primitives(framebuf, SPLAYER_DARKROOM_UNDER);
5183
1/2
✓ Branch 0 taken 11991 times.
✗ Branch 1 not taken.
11991 set_clip_rect(framebuf, 0, playing_field_offset, framebuf->w, framebuf->h);
5184
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11991 times.
11991 if(hero_scr->flags9 & fDARK_DITHER) //dither the entire bitmap
5185 {
5186 ditherblit(darkscr_bmp,darkscr_bmp,0,game->get_dither_type(),game->get_dither_arg());
5187 ditherblit(darkscr_bmp_trans,darkscr_bmp_trans,0,game->get_dither_type(),game->get_dither_arg());
5188 }
5189
5190 11991 color_map = &trans_table2;
5191
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11991 times.
11991 if(hero_scr->flags9 & fDARK_TRANS) //draw the dark as transparent
5192 {
5193 draw_trans_sprite(framebuf, darkscr_bmp, 0, 0);
5194 if(get_qr(qr_NEWDARK_TRANS_STACKING))
5195 draw_trans_sprite(framebuf, darkscr_bmp_trans, 0, 0);
5196 }
5197 else
5198 {
5199
1/2
✓ Branch 0 taken 11991 times.
✗ Branch 1 not taken.
11991 masked_blit(darkscr_bmp, framebuf, 0, 0, 0, 0, framebuf->w, framebuf->h);
5200
1/2
✓ Branch 0 taken 11991 times.
✗ Branch 1 not taken.
11991 draw_trans_sprite(framebuf, darkscr_bmp_trans, 0, 0);
5201 }
5202 11991 color_map = &trans_table;
5203
5204
1/2
✓ Branch 0 taken 11991 times.
✗ Branch 1 not taken.
11991 set_clip_rect(framebuf, 0, 0, framebuf->w, framebuf->h);
5205
1/2
✓ Branch 0 taken 11991 times.
✗ Branch 1 not taken.
11991 do_primitives(framebuf, SPLAYER_DARKROOM_OVER);
5206 11991 }
5207
5208
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 _do_current_ffc_layer(framebuf, 7);
5209
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 draw_msgstr(7);
5210
5211
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 set_clip_rect(scrollbuf, 0, 0, scrollbuf->w, scrollbuf->h);
5212
3/4
✓ Branch 0 taken 14938100 times.
✓ Branch 1 taken 601665 times.
✓ Branch 2 taken 14938100 times.
✗ Branch 3 not taken.
15539765 if(runGeneric) FFCore.runGenericPassiveEngine(SCR_TIMING_POST_DRAW);
5213 76698313 }
5214
5215 // TODO: separate setting door data and drawing door
5216 28153 void put_door(mapscr* scr, BITMAP *dest, int32_t pos, int32_t side, int32_t type, bool redraw, bool even_walls)
5217 {
5218
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 28153 times.
28153 if (type > 8) return;
5219
5220 28153 int32_t d=scr->door_combo_set;
5221
5222
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 15611 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 12542 times.
28153 switch(type)
5223 {
5224 case dt_wall:
5225 case dt_walk:
5226 if(!even_walls)
5227 break;
5228 [[fallthrough]];
5229 case dt_pass:
5230
3/4
✓ Branch 0 taken 1036 times.
✓ Branch 1 taken 11506 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1036 times.
12542 if(!get_qr(qr_REPLACEOPENDOORS) && !even_walls)
5231 1036 break;
5232 [[fallthrough]];
5233 case dt_lock:
5234 case dt_shut:
5235 case dt_boss:
5236 case dt_olck:
5237 case dt_osht:
5238 case dt_obos:
5239 case dt_bomb:
5240
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 7259 times.
✓ Branch 2 taken 6784 times.
✓ Branch 3 taken 6362 times.
✓ Branch 4 taken 6712 times.
27117 switch(side)
5241 {
5242 case up:
5243 7259 scr->data[pos] = DoorComboSets[d].doorcombo_u[type][0];
5244 7259 scr->cset[pos] = DoorComboSets[d].doorcset_u[type][0];
5245 7259 scr->sflag[pos] = 0;
5246 7259 scr->data[pos+1] = DoorComboSets[d].doorcombo_u[type][1];
5247 7259 scr->cset[pos+1] = DoorComboSets[d].doorcset_u[type][1];
5248 7259 scr->sflag[pos+1] = 0;
5249 7259 scr->data[pos+16] = DoorComboSets[d].doorcombo_u[type][2];
5250 7259 scr->cset[pos+16] = DoorComboSets[d].doorcset_u[type][2];
5251 7259 scr->sflag[pos+16] = 0;
5252 7259 scr->data[pos+16+1] = DoorComboSets[d].doorcombo_u[type][3];
5253 7259 scr->cset[pos+16+1] = DoorComboSets[d].doorcset_u[type][3];
5254 7259 scr->sflag[pos+16+1] = 0;
5255
5256
2/2
✓ Branch 0 taken 5435 times.
✓ Branch 1 taken 1824 times.
7259 if(redraw)
5257 {
5258 3648 putcombo(dest,(pos&15)<<4,pos&0xF0,
5259 1824 DoorComboSets[d].doorcombo_u[type][0],
5260 1824 DoorComboSets[d].doorcset_u[type][0]);
5261 3648 putcombo(dest,((pos&15)<<4)+16,pos&0xF0,
5262 1824 DoorComboSets[d].doorcombo_u[type][1],
5263 1824 DoorComboSets[d].doorcset_u[type][1]);
5264 1824 }
5265
5266 7259 break;
5267
5268 case down:
5269 6784 scr->data[pos] = DoorComboSets[d].doorcombo_d[type][0];
5270 6784 scr->cset[pos] = DoorComboSets[d].doorcset_d[type][0];
5271 6784 scr->sflag[pos] = 0;
5272 6784 scr->data[pos+1] = DoorComboSets[d].doorcombo_d[type][1];
5273 6784 scr->cset[pos+1] = DoorComboSets[d].doorcset_d[type][1];
5274 6784 scr->sflag[pos+1] = 0;
5275 6784 scr->data[pos+16] = DoorComboSets[d].doorcombo_d[type][2];
5276 6784 scr->cset[pos+16] = DoorComboSets[d].doorcset_d[type][2];
5277 6784 scr->sflag[pos+16] = 0;
5278 6784 scr->data[pos+16+1] = DoorComboSets[d].doorcombo_d[type][3];
5279 6784 scr->cset[pos+16+1] = DoorComboSets[d].doorcset_d[type][3];
5280 6784 scr->sflag[pos+16+1] = 0;
5281
5282
2/2
✓ Branch 0 taken 5463 times.
✓ Branch 1 taken 1321 times.
6784 if(redraw)
5283 {
5284 2642 putcombo(dest,(pos&15)<<4,(pos&0xF0)+16,
5285 1321 DoorComboSets[d].doorcombo_d[type][2],
5286 1321 DoorComboSets[d].doorcset_d[type][2]);
5287 2642 putcombo(dest,((pos&15)<<4)+16,(pos&0xF0)+16,
5288 1321 DoorComboSets[d].doorcombo_d[type][3],
5289 1321 DoorComboSets[d].doorcset_d[type][3]);
5290 1321 }
5291
5292 6784 break;
5293
5294 case left:
5295 6362 scr->data[pos] = DoorComboSets[d].doorcombo_l[type][0];
5296 6362 scr->cset[pos] = DoorComboSets[d].doorcset_l[type][0];
5297 6362 scr->sflag[pos] = 0;
5298 6362 scr->data[pos+1] = DoorComboSets[d].doorcombo_l[type][1];
5299 6362 scr->cset[pos+1] = DoorComboSets[d].doorcset_l[type][1];
5300 6362 scr->sflag[pos+1] = 0;
5301 6362 scr->data[pos+16] = DoorComboSets[d].doorcombo_l[type][2];
5302 6362 scr->cset[pos+16] = DoorComboSets[d].doorcset_l[type][2];
5303 6362 scr->sflag[pos+16] = 0;
5304 6362 scr->data[pos+16+1] = DoorComboSets[d].doorcombo_l[type][3];
5305 6362 scr->cset[pos+16+1] = DoorComboSets[d].doorcset_l[type][3];
5306 6362 scr->sflag[pos+16+1] = 0;
5307 6362 scr->data[pos+32] = DoorComboSets[d].doorcombo_l[type][4];
5308 6362 scr->cset[pos+32] = DoorComboSets[d].doorcset_l[type][4];
5309 6362 scr->sflag[pos+32] = 0;
5310 6362 scr->data[pos+32+1] = DoorComboSets[d].doorcombo_l[type][5];
5311 6362 scr->cset[pos+32+1] = DoorComboSets[d].doorcset_l[type][5];
5312 6362 scr->sflag[pos+32+1] = 0;
5313
5314
2/2
✓ Branch 0 taken 4873 times.
✓ Branch 1 taken 1489 times.
6362 if(redraw)
5315 {
5316 2978 putcombo(dest,(pos&15)<<4,pos&0xF0,
5317 1489 DoorComboSets[d].doorcombo_l[type][0],
5318 1489 DoorComboSets[d].doorcset_l[type][0]);
5319 2978 putcombo(dest,(pos&15)<<4,(pos&0xF0)+16,
5320 1489 DoorComboSets[d].doorcombo_l[type][2],
5321 1489 DoorComboSets[d].doorcset_l[type][2]);
5322 2978 putcombo(dest,(pos&15)<<4,(pos&0xF0)+32,
5323 1489 DoorComboSets[d].doorcombo_l[type][4],
5324 1489 DoorComboSets[d].doorcset_l[type][4]);
5325 1489 }
5326
5327 6362 break;
5328
5329 case right:
5330 6712 scr->data[pos] = DoorComboSets[d].doorcombo_r[type][0];
5331 6712 scr->cset[pos] = DoorComboSets[d].doorcset_r[type][0];
5332 6712 scr->sflag[pos] = 0;
5333 6712 scr->data[pos+1] = DoorComboSets[d].doorcombo_r[type][1];
5334 6712 scr->cset[pos+1] = DoorComboSets[d].doorcset_r[type][1];
5335 6712 scr->sflag[pos+1] = 0;
5336 6712 scr->data[pos+16] = DoorComboSets[d].doorcombo_r[type][2];
5337 6712 scr->cset[pos+16] = DoorComboSets[d].doorcset_r[type][2];
5338 6712 scr->sflag[pos+16] = 0;
5339 6712 scr->data[pos+16+1] = DoorComboSets[d].doorcombo_r[type][3];
5340 6712 scr->cset[pos+16+1] = DoorComboSets[d].doorcset_r[type][3];
5341 6712 scr->sflag[pos+16+1] = 0;
5342 6712 scr->data[pos+32] = DoorComboSets[d].doorcombo_r[type][4];
5343 6712 scr->cset[pos+32] = DoorComboSets[d].doorcset_r[type][4];
5344 6712 scr->sflag[pos+32] = 0;
5345 6712 scr->data[pos+32+1] = DoorComboSets[d].doorcombo_r[type][5];
5346 6712 scr->cset[pos+32+1] = DoorComboSets[d].doorcset_r[type][5];
5347 6712 scr->sflag[pos+32+1] = 0;
5348
5349
2/2
✓ Branch 0 taken 5058 times.
✓ Branch 1 taken 1654 times.
6712 if(redraw)
5350 {
5351 3308 putcombo(dest,(pos&15)<<4,pos&0xF0,
5352 1654 DoorComboSets[d].doorcombo_r[type][0],
5353 1654 DoorComboSets[d].doorcset_r[type][0]);
5354 3308 putcombo(dest,(pos&15)<<4,(pos&0xF0)+16,
5355 1654 DoorComboSets[d].doorcombo_r[type][2],
5356 1654 DoorComboSets[d].doorcset_r[type][2]);
5357 3308 putcombo(dest,(pos&15)<<4,(pos&0xF0)+32,
5358 1654 DoorComboSets[d].doorcombo_r[type][4],
5359 1654 DoorComboSets[d].doorcset_r[type][4]);
5360 1654 }
5361
5362 6712 break;
5363 }
5364
5365 27117 break;
5366
5367 default:
5368 break;
5369 }
5370 28153 }
5371
5372 706556 static void over_door(mapscr* scr, BITMAP *dest, int32_t pos, int32_t side, int32_t offx, int32_t offy)
5373 {
5374 706556 int32_t door_combo_set = scr->door_combo_set;
5375 706556 int32_t x = (pos&15)<<4;
5376 706556 int32_t y = (pos&0xF0);
5377 706556 int32_t d = door_combo_set;
5378 706556 x += offx;
5379 706556 y += offy;
5380
5381
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 161136 times.
✓ Branch 2 taken 179643 times.
✓ Branch 3 taken 196353 times.
✓ Branch 4 taken 169424 times.
706556 switch(side)
5382 {
5383 case up:
5384 322272 overcombo2(dest,x,y,
5385 161136 DoorComboSets[d].bombdoorcombo_u[0],
5386 161136 DoorComboSets[d].bombdoorcset_u[0]);
5387 322272 overcombo2(dest,x+16,y,
5388 161136 DoorComboSets[d].bombdoorcombo_u[1],
5389 161136 DoorComboSets[d].bombdoorcset_u[1]);
5390 161136 break;
5391
5392 case down:
5393 359286 overcombo2(dest,x,y,
5394 179643 DoorComboSets[d].bombdoorcombo_d[0],
5395 179643 DoorComboSets[d].bombdoorcset_d[0]);
5396 359286 overcombo2(dest,x+16,y,
5397 179643 DoorComboSets[d].bombdoorcombo_d[1],
5398 179643 DoorComboSets[d].bombdoorcset_d[1]);
5399 179643 break;
5400
5401 case left:
5402 392706 overcombo2(dest,x,y,
5403 196353 DoorComboSets[d].bombdoorcombo_l[0],
5404 196353 DoorComboSets[d].bombdoorcset_l[0]);
5405 392706 overcombo2(dest,x,y+16,
5406 196353 DoorComboSets[d].bombdoorcombo_l[1],
5407 196353 DoorComboSets[d].bombdoorcset_l[1]);
5408 392706 overcombo2(dest,x,y+16,
5409 196353 DoorComboSets[d].bombdoorcombo_l[2],
5410 196353 DoorComboSets[d].bombdoorcset_l[2]);
5411 196353 break;
5412
5413 case right:
5414 338848 overcombo2(dest,x,y,
5415 169424 DoorComboSets[d].bombdoorcombo_r[0],
5416 169424 DoorComboSets[d].bombdoorcset_r[0]);
5417 338848 overcombo2(dest,x,y+16,
5418 169424 DoorComboSets[d].bombdoorcombo_r[1],
5419 169424 DoorComboSets[d].bombdoorcset_r[1]);
5420 338848 overcombo2(dest,x,y+16,
5421 169424 DoorComboSets[d].bombdoorcombo_r[2],
5422 169424 DoorComboSets[d].bombdoorcset_r[2]);
5423 169424 break;
5424 }
5425 706556 }
5426
5427 47568 void update_door(mapscr* scr, int32_t side, int32_t door, bool even_walls)
5428 {
5429
7/8
✓ Branch 0 taken 47460 times.
✓ Branch 1 taken 108 times.
✓ Branch 2 taken 47460 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 22925 times.
✓ Branch 5 taken 24535 times.
✓ Branch 6 taken 530 times.
✓ Branch 7 taken 22395 times.
47568 if(door == dNONE || (!even_walls&&(door==dWALL||door==dWALK)))
5430 25173 return;
5431
5432 int32_t doortype;
5433
5434
10/12
✓ Branch 0 taken 522 times.
✓ Branch 1 taken 655 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 12492 times.
✓ Branch 5 taken 910 times.
✓ Branch 6 taken 1553 times.
✓ Branch 7 taken 3192 times.
✓ Branch 8 taken 1694 times.
✓ Branch 9 taken 172 times.
✓ Branch 10 taken 67 times.
✓ Branch 11 taken 1138 times.
22395 switch(door)
5435 {
5436 case dWALL:
5437 doortype=dt_wall;
5438 break;
5439
5440 case dWALK:
5441 doortype=dt_walk;
5442 break;
5443
5444 case dOPEN:
5445 12492 doortype=dt_pass;
5446 12492 break;
5447
5448 case dLOCKED:
5449 910 doortype=dt_lock;
5450 910 break;
5451
5452 case dUNLOCKED:
5453 1553 doortype=dt_olck;
5454 1553 break;
5455
5456 case dSHUTTER:
5457
3/4
✓ Branch 0 taken 2783 times.
✓ Branch 1 taken 409 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2783 times.
3192 if(screenscrolling && ((HeroDir()^1)==side))
5458 {
5459 doortype=dt_osht;
5460 get_screen_state(scr->screen).open_doors = -4;
5461 break;
5462 }
5463
5464 [[fallthrough]];
5465 case d1WAYSHUTTER:
5466 3714 doortype=dt_shut;
5467 3714 break;
5468
5469 case dOPENSHUTTER:
5470 1694 doortype=dt_osht;
5471 1694 break;
5472
5473 case dBOSS:
5474 172 doortype=dt_boss;
5475 172 break;
5476
5477 case dOPENBOSS:
5478 67 doortype=dt_obos;
5479 67 break;
5480
5481 case dBOMBED:
5482 1138 doortype=dt_bomb;
5483 1138 break;
5484
5485 default:
5486 655 return;
5487 }
5488
5489
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 5629 times.
✓ Branch 2 taken 5770 times.
✓ Branch 3 taken 5111 times.
✓ Branch 4 taken 5230 times.
21740 switch(side)
5490 {
5491 case up:
5492 5629 put_door(scr,nullptr,7,side,doortype,false,even_walls);
5493 5629 break;
5494
5495 case down:
5496 5770 put_door(scr,nullptr,151,side,doortype,false,even_walls);
5497 5770 break;
5498
5499 case left:
5500 5111 put_door(scr,nullptr,64,side,doortype,false,even_walls);
5501 5111 break;
5502
5503 case right:
5504 5230 put_door(scr,nullptr,78,side,doortype,false,even_walls);
5505 5230 break;
5506 }
5507 47568 }
5508
5509 6504 void putdoor(mapscr* scr, BITMAP *dest, int32_t side, int32_t door, bool redraw, bool even_walls)
5510 {
5511 /*
5512 #define dWALL 0 // 000 0
5513 #define dBOMB 6 // 011 0
5514 #define 8 // 100 0
5515 enum {dt_pass=0, dt_lock, dt_shut, dt_boss, dt_olck, dt_osht, dt_obos, dt_wall, dt_bomb, dt_walk, dt_max};
5516 */
5517
5518
7/8
✓ Branch 0 taken 6504 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6500 times.
✓ Branch 3 taken 4 times.
✓ Branch 4 taken 6417 times.
✓ Branch 5 taken 83 times.
✓ Branch 6 taken 8 times.
✓ Branch 7 taken 6409 times.
6504 if(door == dNONE || (!even_walls&&(door==dWALL||door==dWALK)))
5519 91 return;
5520
5521 int32_t doortype;
5522
5523
8/12
✓ Branch 0 taken 227 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 50 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 362 times.
✓ Branch 7 taken 1530 times.
✓ Branch 8 taken 3958 times.
✓ Branch 9 taken 4 times.
✓ Branch 10 taken 51 times.
✓ Branch 11 taken 231 times.
6413 switch(door)
5524 {
5525 case dWALL:
5526 doortype=dt_wall;
5527 break;
5528
5529 case dWALK:
5530 doortype=dt_walk;
5531 break;
5532
5533 case dOPEN:
5534 50 doortype=dt_pass;
5535 50 break;
5536
5537 case dLOCKED:
5538 doortype=dt_lock;
5539 break;
5540
5541 case dUNLOCKED:
5542 362 doortype=dt_olck;
5543 362 break;
5544
5545 case dSHUTTER:
5546
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1530 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1530 if(screenscrolling && ((HeroDir()^1)==side))
5547 {
5548 doortype=dt_osht;
5549 get_screen_state(cur_screen).open_doors = -4;
5550 break;
5551 }
5552
5553 [[fallthrough]];
5554 case d1WAYSHUTTER:
5555 1757 doortype=dt_shut;
5556 1757 break;
5557
5558 case dOPENSHUTTER:
5559 3958 doortype=dt_osht;
5560 3958 break;
5561
5562 case dBOSS:
5563 4 doortype=dt_boss;
5564 4 break;
5565
5566 case dOPENBOSS:
5567 51 doortype=dt_obos;
5568 51 break;
5569
5570 case dBOMBED:
5571 231 doortype=dt_bomb;
5572 231 break;
5573
5574 default:
5575 return;
5576 }
5577
5578
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 1860 times.
✓ Branch 2 taken 1357 times.
✓ Branch 3 taken 1514 times.
✓ Branch 4 taken 1682 times.
6413 switch(side)
5579 {
5580 case up:
5581
2/2
✓ Branch 0 taken 1791 times.
✓ Branch 1 taken 69 times.
1860 switch(door)
5582 {
5583 case dBOMBED:
5584
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 69 times.
138 if(redraw)
5585 {
5586 69 over_door(scr,dest,39,side,0,0);
5587 69 }
5588 [[fallthrough]];
5589 default:
5590 1860 put_door(scr,dest,7,side,doortype,redraw, even_walls);
5591 1860 break;
5592 }
5593
5594 1860 break;
5595
5596 case down:
5597
2/2
✓ Branch 0 taken 1318 times.
✓ Branch 1 taken 39 times.
1357 switch(door)
5598 {
5599 case dBOMBED:
5600
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 39 times.
78 if(redraw)
5601 {
5602 39 over_door(scr,dest,135,side,0,0);
5603 39 }
5604 [[fallthrough]];
5605 default:
5606 1357 put_door(scr,dest,151,side,doortype,redraw, even_walls);
5607 1357 break;
5608 }
5609
5610 1357 break;
5611
5612 case left:
5613
2/2
✓ Branch 0 taken 1463 times.
✓ Branch 1 taken 51 times.
1514 switch(door)
5614 {
5615 case dBOMBED:
5616
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 51 times.
102 if(redraw)
5617 {
5618 51 over_door(scr,dest,66,side,0,0);
5619 51 }
5620 [[fallthrough]];
5621 default:
5622 1514 put_door(scr,dest,64,side,doortype,redraw, even_walls);
5623 1514 break;
5624 }
5625
5626 1514 break;
5627
5628 case right:
5629
2/2
✓ Branch 0 taken 1610 times.
✓ Branch 1 taken 72 times.
1682 switch(door)
5630 {
5631 case dBOMBED:
5632
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 72 times.
144 if(redraw)
5633 {
5634 72 over_door(scr,dest,77,side,0,0);
5635 72 }
5636 [[fallthrough]];
5637 default:
5638 1682 put_door(scr,dest,78,side,doortype,redraw, even_walls);
5639 1682 break;
5640 }
5641
5642 1682 break;
5643 }
5644 6504 }
5645
5646 586 void putcombo_not_zero(BITMAP *dest, int32_t x, int32_t y, int32_t combo, int32_t cset)
5647 {
5648
1/2
✓ Branch 0 taken 586 times.
✗ Branch 1 not taken.
586 if(combo!=0)
5649 {
5650 586 putcombo(dest,x, y, combo, cset);
5651 586 }
5652 586 }
5653
5654 293 void overcombo_not_zero(BITMAP *dest, int32_t x, int32_t y, int32_t combo, int32_t cset)
5655 {
5656
2/2
✓ Branch 0 taken 219 times.
✓ Branch 1 taken 74 times.
293 if(combo!=0)
5657 {
5658 219 overcombo(dest,x, y, combo, cset);
5659 219 }
5660 293 }
5661
5662 125 void showbombeddoor(mapscr* scr, BITMAP *dest, int32_t side, int32_t offx, int32_t offy)
5663 {
5664 125 int32_t d = scr->door_combo_set;
5665
5666
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 43 times.
✓ Branch 2 taken 39 times.
✓ Branch 3 taken 6 times.
✓ Branch 4 taken 37 times.
125 switch(side)
5667 {
5668 case up:
5669 86 putcombo_not_zero(dest,((7&15)<<4) + offx,(7&0xF0) + offy,
5670 43 DoorComboSets[d].doorcombo_u[dt_bomb][0],
5671 43 DoorComboSets[d].doorcset_u[dt_bomb][0]);
5672 86 putcombo_not_zero(dest,((8&15)<<4) + offx,(8&0xF0) + offy,
5673 43 DoorComboSets[d].doorcombo_u[dt_bomb][1],
5674 43 DoorComboSets[d].doorcset_u[dt_bomb][1]);
5675 86 putcombo_not_zero(dest,((23&15)<<4) + offx,(23&0xF0) + offy,
5676 43 DoorComboSets[d].doorcombo_u[dt_bomb][2],
5677 43 DoorComboSets[d].doorcset_u[dt_bomb][2]);
5678 86 putcombo_not_zero(dest,((24&15)<<4) + offx,(24&0xF0) + offy,
5679 43 DoorComboSets[d].doorcombo_u[dt_bomb][3],
5680 43 DoorComboSets[d].doorcset_u[dt_bomb][3]);
5681 86 overcombo_not_zero(dest,((39&15)<<4) + offx,(39&0xF0) + offy,
5682 43 DoorComboSets[d].bombdoorcombo_u[0],
5683 43 DoorComboSets[d].bombdoorcset_u[0]);
5684 86 overcombo_not_zero(dest,((40&15)<<4) + offx,(40&0xF0) + offy,
5685 43 DoorComboSets[d].bombdoorcombo_u[1],
5686 43 DoorComboSets[d].bombdoorcset_u[1]);
5687 43 break;
5688
5689 case down:
5690 78 putcombo_not_zero(dest,((151&15)<<4) + offx,(151&0xF0) + offy,
5691 39 DoorComboSets[d].doorcombo_d[dt_bomb][0],
5692 39 DoorComboSets[d].doorcset_d[dt_bomb][0]);
5693 78 putcombo_not_zero(dest,((152&15)<<4) + offx,(152&0xF0) + offy,
5694 39 DoorComboSets[d].doorcombo_d[dt_bomb][1],
5695 39 DoorComboSets[d].doorcset_d[dt_bomb][1]);
5696 78 putcombo_not_zero(dest,((167&15)<<4) + offx,(167&0xF0) + offy,
5697 39 DoorComboSets[d].doorcombo_d[dt_bomb][2],
5698 39 DoorComboSets[d].doorcset_d[dt_bomb][2]);
5699 78 putcombo_not_zero(dest,((168&15)<<4) + offx,(168&0xF0) + offy,
5700 39 DoorComboSets[d].doorcombo_d[dt_bomb][3],
5701 39 DoorComboSets[d].doorcset_d[dt_bomb][3]);
5702 78 overcombo_not_zero(dest,((135&15)<<4) + offx,(135&0xF0) + offy,
5703 39 DoorComboSets[d].bombdoorcombo_d[0],
5704 39 DoorComboSets[d].bombdoorcset_d[0]);
5705 78 overcombo_not_zero(dest,((136&15)<<4) + offx,(136&0xF0) + offy,
5706 39 DoorComboSets[d].bombdoorcombo_d[1],
5707 39 DoorComboSets[d].bombdoorcset_d[1]);
5708 39 break;
5709
5710 case left:
5711 12 putcombo_not_zero(dest,((64&15)<<4) + offx,(64&0xF0) + offy,
5712 6 DoorComboSets[d].doorcombo_l[dt_bomb][0],
5713 6 DoorComboSets[d].doorcset_l[dt_bomb][0]);
5714 12 putcombo_not_zero(dest,((65&15)<<4) + offx,(65&0xF0) + offy,
5715 6 DoorComboSets[d].doorcombo_l[dt_bomb][1],
5716 6 DoorComboSets[d].doorcset_l[dt_bomb][1]);
5717 12 putcombo_not_zero(dest,((80&15)<<4) + offx,(80&0xF0) + offy,
5718 6 DoorComboSets[d].doorcombo_l[dt_bomb][2],
5719 6 DoorComboSets[d].doorcset_l[dt_bomb][2]);
5720 12 putcombo_not_zero(dest,((81&15)<<4) + offx,(81&0xF0) + offy,
5721 6 DoorComboSets[d].doorcombo_l[dt_bomb][3],
5722 6 DoorComboSets[d].doorcset_l[dt_bomb][3]);
5723 12 putcombo_not_zero(dest,((96&15)<<4) + offx,(96&0xF0) + offy,
5724 6 DoorComboSets[d].doorcombo_l[dt_bomb][4],
5725 6 DoorComboSets[d].doorcset_l[dt_bomb][4]);
5726 12 putcombo_not_zero(dest,((97&15)<<4) + offx,(97&0xF0) + offy,
5727 6 DoorComboSets[d].doorcombo_l[dt_bomb][5],
5728 6 DoorComboSets[d].doorcset_l[dt_bomb][5]);
5729 12 overcombo_not_zero(dest,((66&15)<<4) + offx,(66&0xF0) + offy,
5730 6 DoorComboSets[d].bombdoorcombo_l[0],
5731 6 DoorComboSets[d].bombdoorcset_l[0]);
5732 12 overcombo_not_zero(dest,((82&15)<<4) + offx,(82&0xF0) + offy,
5733 6 DoorComboSets[d].bombdoorcombo_l[1],
5734 6 DoorComboSets[d].bombdoorcset_l[1]);
5735 12 overcombo_not_zero(dest,((98&15)<<4) + offx,(98&0xF0) + offy,
5736 6 DoorComboSets[d].bombdoorcombo_l[2],
5737 6 DoorComboSets[d].bombdoorcset_l[2]);
5738 6 break;
5739
5740 case right:
5741 74 putcombo_not_zero(dest,((78&15)<<4) + offx,(78&0xF0) + offy,
5742 37 DoorComboSets[d].doorcombo_r[dt_bomb][0],
5743 37 DoorComboSets[d].doorcset_r[dt_bomb][0]);
5744 74 putcombo_not_zero(dest,((79&15)<<4) + offx,(79&0xF0) + offy,
5745 37 DoorComboSets[d].doorcombo_r[dt_bomb][1],
5746 37 DoorComboSets[d].doorcset_r[dt_bomb][1]);
5747 74 putcombo_not_zero(dest,((94&15)<<4) + offx,(94&0xF0) + offy,
5748 37 DoorComboSets[d].doorcombo_r[dt_bomb][2],
5749 37 DoorComboSets[d].doorcset_r[dt_bomb][2]);
5750 74 putcombo_not_zero(dest,((95&15)<<4) + offx,(95&0xF0) + offy,
5751 37 DoorComboSets[d].doorcombo_r[dt_bomb][3],
5752 37 DoorComboSets[d].doorcset_r[dt_bomb][3]);
5753 74 putcombo_not_zero(dest,((110&15)<<4) + offx,(110&0xF0) + offy,
5754 37 DoorComboSets[d].doorcombo_r[dt_bomb][4],
5755 37 DoorComboSets[d].doorcset_r[dt_bomb][4]);
5756 74 putcombo_not_zero(dest,((111&15)<<4) + offx,(111&0xF0) + offy,
5757 37 DoorComboSets[d].doorcombo_r[dt_bomb][5],
5758 37 DoorComboSets[d].doorcset_r[dt_bomb][5]);
5759 74 overcombo_not_zero(dest,((77&15)<<4) + offx,(77&0xF0) + offy,
5760 37 DoorComboSets[d].bombdoorcombo_r[0],
5761 37 DoorComboSets[d].bombdoorcset_r[0]);
5762 74 overcombo_not_zero(dest,((93&15)<<4) + offx,(93&0xF0) + offy,
5763 37 DoorComboSets[d].bombdoorcombo_r[1],
5764 37 DoorComboSets[d].bombdoorcset_r[1]);
5765 74 overcombo_not_zero(dest,((109&15)<<4) + offx,(109&0xF0) + offy,
5766 37 DoorComboSets[d].bombdoorcombo_r[2],
5767 37 DoorComboSets[d].bombdoorcset_r[2]);
5768 37 break;
5769 }
5770 125 }
5771
5772 5357371 void openshutters(mapscr* scr)
5773 {
5774 5357371 bool opened_door = false;
5775
2/2
✓ Branch 0 taken 5357371 times.
✓ Branch 1 taken 21429484 times.
26786855 for(int32_t i=0; i<4; i++)
5776
2/2
✓ Branch 0 taken 21425526 times.
✓ Branch 1 taken 3958 times.
21433442 if(scr->door[i]==dSHUTTER)
5777 {
5778 3958 putdoor(scr, scrollbuf, i, dOPENSHUTTER);
5779 3958 scr->door[i]=dOPENSHUTTER;
5780 3958 opened_door = true;
5781 3958 }
5782
5783 5357371 auto& combo_cache = combo_caches::shutter;
5784 2020175719 for_every_combo_in_screen(create_screen_handles(scr), [&](const auto& handle) {
5785
3/4
✓ Branch 0 taken 2013207673 times.
✓ Branch 1 taken 7 times.
✓ Branch 2 taken 1610668 times.
✗ Branch 3 not taken.
2014818348 if (!combo_cache.minis[handle.data()].shutter)
5786 2014818341 return;
5787
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
14 trig_each_combo_trigger(handle, [&](combo_trigger const& trig){
5788 7 return trig.trigger_flags.get(TRIGFLAG_SHUTTER);
5789 });
5790 2014818348 });
5791
5792
2/2
✓ Branch 0 taken 5354640 times.
✓ Branch 1 taken 2731 times.
5357371 if(opened_door)
5793 2731 sfx(WAV_DOOR,128);
5794 5357371 }
5795
5796 15116782 void clear_darkroom_bitmaps()
5797 {
5798 15116782 clear_to_color(darkscr_bmp, game->get_darkscr_color());
5799 15116782 clear_to_color(darkscr_bmp_trans, game->get_darkscr_color());
5800 15116782 }
5801
5802 16031111 bool is_dark(const mapscr* scr)
5803 {
5804 16031111 bool dark = scr->flags&fDARK;
5805
2/2
✓ Branch 0 taken 3722 times.
✓ Branch 1 taken 16027389 times.
16031111 if (region_is_lit) return !dark;
5806 16027389 return dark;
5807 16031111 }
5808
5809 39226 bool scrolling_is_dark(const mapscr* scr)
5810 {
5811 39226 bool dark = scr->flags&fDARK;
5812
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 39224 times.
39226 if (scrolling_region_is_lit) return !dark;
5813 39224 return dark;
5814 39226 }
5815
5816 36758 bool is_any_dark()
5817 {
5818 36758 bool dark = false;
5819 74772 for_every_base_screen_in_region([&](mapscr* scr, unsigned int region_scr_x, unsigned int region_scr_y) {
5820 38014 dark |= (bool)(is_dark(scr));
5821 38014 });
5822 36758 return dark;
5823 }
5824
5825 412 static mapscr prev_origin_scrs[7];
5826 412 static std::set<int> loadscr_ffc_script_ids_to_remove;
5827
5828 static void handle_screen_overlay(const std::vector<mapscr*>& screens)
5829 {
5830 mapscr* base_scr = screens[0];
5831 mapscr* previous_scr = &prev_origin_scrs[0];
5832
5833 for (int i = 0; i < 176; i++)
5834 {
5835 if (base_scr->data[i] == 0)
5836 {
5837 base_scr->data[i] = previous_scr->data[i];
5838 base_scr->sflag[i] = previous_scr->sflag[i];
5839 base_scr->cset[i] = previous_scr->cset[i];
5840 }
5841 }
5842
5843 for (int i = 0; i < 6; i++)
5844 {
5845 if (previous_scr->layermap[i] > 0 && base_scr->layermap[i] > 0)
5846 {
5847 int lm = (base_scr->layermap[i]-1)*MAPSCRS+base_scr->layerscreen[i];
5848 int fm = (previous_scr->layermap[i]-1)*MAPSCRS+previous_scr->layerscreen[i];
5849
5850 for (int j = 0; j < 176; j++)
5851 {
5852 if (TheMaps[lm].data[j] == 0)
5853 {
5854 TheMaps[lm].data[j] = TheMaps[fm].data[j];
5855 TheMaps[lm].sflag[j] = TheMaps[fm].sflag[j];
5856 TheMaps[lm].cset[j] = TheMaps[fm].cset[j];
5857 }
5858 }
5859 }
5860 }
5861
5862 for (int i = 1; i <= 6; i++)
5863 {
5864 mapscr* scr = screens[i];
5865 previous_scr = &prev_origin_scrs[i];
5866
5867 if (scr->layermap[i] > 0)
5868 {
5869 for (int y = 0; y < 11; y++)
5870 {
5871 for (int x = 0; x < 16; x++)
5872 {
5873 int c = y*16+x;
5874
5875 if (scr->data[c]==0)
5876 {
5877 scr->data[c] = previous_scr->data[c];
5878 scr->sflag[c] = previous_scr->sflag[c];
5879 scr->cset[c] = previous_scr->cset[c];
5880 }
5881 }
5882 }
5883 }
5884 }
5885 }
5886
5887 37098 static void load_a_screen_and_layers_init(int dmap, int screen, int ldir, bool screen_overlay, bool ffc_overlay)
5888 {
5889 37098 std::vector<mapscr*> screens;
5890
5891
1/2
✓ Branch 0 taken 37098 times.
✗ Branch 1 not taken.
37098 const mapscr* source = get_canonical_scr(cur_map, screen);
5892
2/4
✓ Branch 0 taken 37098 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 37098 times.
✗ Branch 3 not taken.
37098 mapscr* base_scr = new mapscr(*source);
5893 37098 temporary_screens[screen*7] = base_scr;
5894
1/2
✓ Branch 0 taken 37098 times.
✗ Branch 1 not taken.
37098 screens.push_back(base_scr);
5895
5896 37098 base_scr->valid |= mVALID; // layer 0 is always valid
5897
5898
2/2
✓ Branch 0 taken 1244 times.
✓ Branch 1 taken 35854 times.
37098 if (screen == cur_screen)
5899 35854 origin_scr = base_scr;
5900
2/2
✓ Branch 0 taken 1244 times.
✓ Branch 1 taken 35854 times.
37098 if (screen == hero_screen)
5901 35854 hero_scr = prev_hero_scr = base_scr;
5902
5903
2/2
✓ Branch 0 taken 119 times.
✓ Branch 1 taken 36979 times.
37098 if (source->script > 0)
5904
1/2
✓ Branch 0 taken 119 times.
✗ Branch 1 not taken.
119 FFCore.reset_script_engine_data(ScriptType::Screen, screen);
5905
5906
2/2
✓ Branch 0 taken 37098 times.
✓ Branch 1 taken 222588 times.
259686 for (int i = 0; i < 6; i++)
5907 {
5908
2/2
✓ Branch 0 taken 173511 times.
✓ Branch 1 taken 49077 times.
222588 if(source->layermap[i]>0)
5909 {
5910
3/6
✓ Branch 0 taken 49077 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 49077 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 49077 times.
✗ Branch 5 not taken.
49077 mapscr* layer_scr = new mapscr(*get_canonical_scr(source->layermap[i]-1, source->layerscreen[i]));
5911 49077 layer_scr->map = cur_map;
5912 49077 layer_scr->screen = screen;
5913
1/2
✓ Branch 0 taken 49077 times.
✗ Branch 1 not taken.
49077 screens.push_back(layer_scr);
5914 49077 }
5915 else
5916 {
5917
1/2
✓ Branch 0 taken 173511 times.
✗ Branch 1 not taken.
173511 mapscr* layer_scr = new mapscr();
5918 173511 layer_scr->map = cur_map;
5919 173511 layer_scr->screen = screen;
5920
1/2
✓ Branch 0 taken 173511 times.
✗ Branch 1 not taken.
173511 screens.push_back(layer_scr);
5921 }
5922 222588 temporary_screens[screen*7+i+1] = screens[i+1];
5923 222588 }
5924
5925
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 37098 times.
37098 if (screen_overlay)
5926 handle_screen_overlay(screens);
5927
5928
2/2
✓ Branch 0 taken 144 times.
✓ Branch 1 taken 36954 times.
37098 if (ffc_overlay)
5929 {
5930 144 mapscr* previous_scr = &prev_origin_scrs[0];
5931
1/2
✓ Branch 0 taken 144 times.
✗ Branch 1 not taken.
144 int num_ffcs = previous_scr->numFFC();
5932
2/2
✓ Branch 0 taken 4608 times.
✓ Branch 1 taken 144 times.
4752 for (int i = 0; i < num_ffcs; i++)
5933 {
5934
2/2
✓ Branch 0 taken 4334 times.
✓ Branch 1 taken 274 times.
4608 if ((previous_scr->ffcs[i].flags&ffc_carryover))
5935 {
5936
2/4
✓ Branch 0 taken 274 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 274 times.
✗ Branch 3 not taken.
274 auto& ffc = base_scr->getFFC(i) = previous_scr->ffcs[i];
5937 274 ffc.screen_spawned = screen;
5938
5939
1/2
✓ Branch 0 taken 274 times.
✗ Branch 1 not taken.
274 ffc_id_t ffc_id = get_region_screen_offset(screen)*MAXFFCS + i;
5940
1/2
✓ Branch 0 taken 274 times.
✗ Branch 1 not taken.
274 loadscr_ffc_script_ids_to_remove.erase(ffc_id);
5941
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 274 times.
274 if (previous_scr->ffcs[i].flags&ffc_scriptreset)
5942 {
5943 FFCore.reset_script_engine_data(ScriptType::FFC, ffc_id);
5944 }
5945 274 }
5946 4608 }
5947 144 }
5948
5949
1/2
✓ Branch 0 taken 37098 times.
✗ Branch 1 not taken.
1141914 auto [offx, offy] = translate_screen_coordinates_to_world(screen);
5950
1/2
✓ Branch 0 taken 37098 times.
✗ Branch 1 not taken.
37098 int num_ffcs = base_scr->numFFC();
5951
2/2
✓ Branch 0 taken 1104816 times.
✓ Branch 1 taken 37098 times.
1141914 for (word i = 0; i < num_ffcs; i++)
5952 {
5953 1104816 base_scr->ffcs[i].screen_spawned = screen;
5954
1/2
✓ Branch 0 taken 1104816 times.
✗ Branch 1 not taken.
1104816 base_scr->ffcs[i].x += offx;
5955
1/2
✓ Branch 0 taken 1104816 times.
✗ Branch 1 not taken.
1104816 base_scr->ffcs[i].y += offy;
5956 1104816 }
5957 37098 }
5958
5959 37098 static void load_a_screen_and_layers_post(int dmap, int screen, int ldir)
5960 {
5961 37098 mapscr* base_scr = get_scr(screen);
5962 37098 int mi = mapind(cur_map, screen);
5963
5964 // Apply perm secrets, if applicable.
5965
2/2
✓ Branch 0 taken 11520 times.
✓ Branch 1 taken 25578 times.
37098 if (canPermSecret(dmap, screen))
5966 {
5967
2/2
✓ Branch 0 taken 23053 times.
✓ Branch 1 taken 2525 times.
25578 if(game->maps[mi] & mSECRET) // if special stuff done before
5968 {
5969 2525 reveal_hidden_stairs(base_scr, screen, false);
5970 2525 trigger_secrets_for_screen(TriggerSource::SecretsScreenState, base_scr, false);
5971 2525 }
5972
2/2
✓ Branch 0 taken 25575 times.
✓ Branch 1 taken 3 times.
25578 if(game->maps[mi] & mLIGHTBEAM) // if special stuff done before
5973 {
5974
2/2
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 3 times.
24 for (int layer = 0; layer <= 6; layer++)
5975 {
5976 21 mapscr* layer_scr = get_scr_layer(screen, layer);
5977
2/2
✓ Branch 0 taken 3696 times.
✓ Branch 1 taken 21 times.
3717 for (int pos = 0; pos < 176; pos++)
5978 {
5979 3696 newcombo const* cmb = &combobuf[layer_scr->data[pos]];
5980
2/2
✓ Branch 0 taken 3693 times.
✓ Branch 1 taken 3 times.
3696 if(cmb->type == cLIGHTTARGET)
5981 {
5982
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (!(cmb->usrflags&cflag1)) //Unlit version
5983 {
5984 3 layer_scr->data[pos] += 1;
5985 3 }
5986 3 }
5987 3696 }
5988 21 }
5989 3 }
5990 25578 }
5991
5992 37098 auto screen_handles = create_screen_handles(base_scr);
5993
5994 37098 int destlvl = DMaps[dmap].level;
5995 37098 toggle_switches(game->lvlswitches[destlvl], true, screen_handles);
5996 37098 toggle_gswitches_load(screen_handles);
5997
5998 37098 bool should_check_for_state_things = (screen < 0x80);
5999
2/2
✓ Branch 0 taken 907 times.
✓ Branch 1 taken 36191 times.
37098 if (should_check_for_state_things)
6000 {
6001
2/2
✓ Branch 0 taken 35819 times.
✓ Branch 1 taken 372 times.
36191 if (game->maps[mi]&mLOCKBLOCK)
6002 372 remove_lockblocks(screen_handles);
6003
2/2
✓ Branch 0 taken 36133 times.
✓ Branch 1 taken 58 times.
36191 if (game->maps[mi]&mBOSSLOCKBLOCK)
6004 58 remove_bosslockblocks(screen_handles);
6005
2/2
✓ Branch 0 taken 36035 times.
✓ Branch 1 taken 156 times.
36191 if (game->maps[mi]&mCHEST)
6006 156 remove_chests(screen_handles);
6007
1/2
✓ Branch 0 taken 36191 times.
✗ Branch 1 not taken.
36191 if (game->maps[mi]&mLOCKEDCHEST)
6008 remove_lockedchests(screen_handles);
6009
2/2
✓ Branch 0 taken 36180 times.
✓ Branch 1 taken 11 times.
36191 if (game->maps[mi]&mBOSSCHEST)
6010 11 remove_bosschests(screen_handles);
6011
6012 36191 clear_xdoors_mi(screen_handles, mi, true);
6013 36191 clear_xstatecombos_mi(screen_handles, mi, true);
6014 36191 }
6015
6016 // check doors
6017
2/2
✓ Branch 0 taken 25577 times.
✓ Branch 1 taken 11521 times.
37098 if (isdungeon(dmap, screen))
6018 {
6019
2/2
✓ Branch 0 taken 46084 times.
✓ Branch 1 taken 11521 times.
57605 for(int32_t i=0; i<4; i++)
6020 {
6021 46084 int32_t door=base_scr->door[i];
6022
6023
5/5
✓ Branch 0 taken 5303 times.
✓ Branch 1 taken 36475 times.
✓ Branch 2 taken 2372 times.
✓ Branch 3 taken 230 times.
✓ Branch 4 taken 1704 times.
46084 switch(door)
6024 {
6025 case d1WAYSHUTTER:
6026 case dSHUTTER:
6027
3/4
✓ Branch 0 taken 1694 times.
✓ Branch 1 taken 3609 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1694 times.
5303 if ((ldir^1)==i && screen == hero_screen)
6028 {
6029 1694 base_scr->door[i]=dOPENSHUTTER;
6030 1694 }
6031
6032 5303 get_screen_state(screen).open_doors = -4;
6033 5303 break;
6034
6035 case dLOCKED:
6036
3/4
✓ Branch 0 taken 2372 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1473 times.
✓ Branch 3 taken 899 times.
2372 if(should_check_for_state_things && game->maps[mi]&(mDOOR_UP<<i))
6037 {
6038 1473 base_scr->door[i]=dUNLOCKED;
6039 1473 }
6040
6041 2372 break;
6042
6043 case dBOSS:
6044
3/4
✓ Branch 0 taken 230 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 62 times.
✓ Branch 3 taken 168 times.
230 if(should_check_for_state_things && game->maps[mi]&(mDOOR_UP<<i))
6045 {
6046 62 base_scr->door[i]=dOPENBOSS;
6047 62 }
6048
6049 230 break;
6050
6051 case dBOMB:
6052
3/4
✓ Branch 0 taken 1704 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1087 times.
✓ Branch 3 taken 617 times.
1704 if(should_check_for_state_things && game->maps[mi]&(mDOOR_UP<<i))
6053 {
6054 1087 base_scr->door[i]=dBOMBED;
6055 1087 }
6056
6057 1704 break;
6058 }
6059
6060 46084 update_door(base_scr, i, base_scr->door[i]);
6061
6062
4/4
✓ Branch 0 taken 41517 times.
✓ Branch 1 taken 4567 times.
✓ Branch 2 taken 736 times.
✓ Branch 3 taken 40781 times.
46084 if(door==dSHUTTER||door==d1WAYSHUTTER)
6063 {
6064 5303 base_scr->door[i]=door;
6065 5303 }
6066 46084 }
6067 11521 }
6068
6069
2/2
✓ Branch 0 taken 137 times.
✓ Branch 1 taken 36961 times.
37098 if (!(base_scr->flags3 & fCYCLEONINIT))
6070 36961 return;
6071
6072
2/2
✓ Branch 0 taken 137 times.
✓ Branch 1 taken 959 times.
1096 for (int32_t j=-1; j<6; ++j) // j == -1 denotes the current screen
6073 {
6074
4/4
✓ Branch 0 taken 822 times.
✓ Branch 1 taken 137 times.
✓ Branch 2 taken 377 times.
✓ Branch 3 taken 445 times.
959 if (j<0 || base_scr->layermap[j] > 0)
6075 {
6076 514 mapscr* layer_scr = get_scr_layer(screen, j + 1);
6077
3/4
✓ Branch 0 taken 377 times.
✓ Branch 1 taken 137 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 377 times.
514 mapscr* layerscreen= (j<0 ? base_scr : layer_scr->valid ? layer_scr :
6078 &TheMaps[(base_scr->layermap[j]-1)*MAPSCRS]+base_scr->layerscreen[j]);
6079
6080
2/2
✓ Branch 0 taken 90464 times.
✓ Branch 1 taken 514 times.
90978 for(int32_t i=0; i<176; ++i)
6081 {
6082 90464 int32_t c=layerscreen->data[i];
6083
6084 // New screen flag: Cycle Combos At Screen Init
6085
5/6
✓ Branch 0 taken 65 times.
✓ Branch 1 taken 90399 times.
✓ Branch 2 taken 29 times.
✓ Branch 3 taken 36 times.
✓ Branch 4 taken 29 times.
✗ Branch 5 not taken.
90464 if(combobuf[c].nextcombo != 0 && (j<0 || get_qr(qr_CMBCYCLELAYERS)))
6086 {
6087 65 int32_t r = 0;
6088
6089
4/4
✓ Branch 0 taken 65 times.
✓ Branch 1 taken 84 times.
✓ Branch 2 taken 84 times.
✓ Branch 3 taken 65 times.
149 while(combobuf[c].can_cycle() && r++ < 10)
6090 {
6091 84 newcombo const& cmb = combobuf[c];
6092 84 bool cycle_under = (cmb.animflags & AF_CYCLEUNDERCOMBO);
6093
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 84 times.
84 auto cid = cycle_under ? layerscreen->undercombo : cmb.nextcombo;
6094 84 layerscreen->data[i] = cid;
6095
2/2
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 69 times.
84 if(!(combobuf[c].animflags & AF_CYCLENOCSET))
6096
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 69 times.
69 layerscreen->cset[i] = cycle_under ? layerscreen->undercset : cmb.nextcset;
6097 84 c = layerscreen->data[i];
6098 }
6099 65 }
6100 90464 }
6101 514 }
6102 959 }
6103 37098 }
6104
6105 // Set `cur_screen` to `screen` and load new screens into temporary memory.
6106 //
6107 // Called anytime a player moves to a new screen (either via warping, scrolling, continue, starting
6108 // the game, etc...)
6109 //
6110 // Note: for regions, only the initial screen load calls this function. Simply walking between
6111 // screens in the same region does not use this, because every screen in a region is loaded into
6112 // temporary memory up front.
6113 //
6114 // If scr >= 0x80, `hero_screen` will be saved to `home_screen` and also be loaded into
6115 // `special_warp_return_scr`.
6116 //
6117 // If origin_screen_overlay is true, the old origin_scr combos will be copied to the new origin_scr combos
6118 // on all layers (but only where the new screen has a 0 combo).
6119 //
6120 // TODO: loadscr should set curdmap, but currently callers do that.
6121 35854 void loadscr(int32_t destdmap, int32_t screen, int32_t ldir, bool origin_screen_overlay, bool no_x80_dir)
6122 {
6123 35854 zapp_reporting_set_tag("screen", screen);
6124
2/2
✓ Branch 0 taken 8928 times.
✓ Branch 1 taken 26926 times.
35854 if (destdmap != -1)
6125 8928 zapp_reporting_set_tag("dmap", destdmap);
6126
6127 35854 int32_t orig_destdmap = destdmap;
6128
2/2
✓ Branch 0 taken 8928 times.
✓ Branch 1 taken 26926 times.
35854 if (destdmap < 0) destdmap = cur_dmap;
6129
6130
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 35854 times.
35854 if (replay_is_active())
6131 {
6132
1/2
✓ Branch 0 taken 35854 times.
✗ Branch 1 not taken.
35854 if (replay_get_mode() == ReplayMode::ManualTakeover)
6133 replay_stop_manual_takeover();
6134
6135
2/2
✓ Branch 0 taken 26926 times.
✓ Branch 1 taken 8928 times.
35854 if (orig_destdmap != -1)
6136 {
6137
2/2
✓ Branch 0 taken 7857 times.
✓ Branch 1 taken 1071 times.
8928 if (strlen(DMaps[orig_destdmap].name) > 0)
6138 {
6139
1/2
✓ Branch 0 taken 7857 times.
✗ Branch 1 not taken.
7857 replay_step_comment(fmt::format("dmap={} {}", orig_destdmap, DMaps[orig_destdmap].name));
6140 7857 }
6141 else
6142 {
6143
1/2
✓ Branch 0 taken 1071 times.
✗ Branch 1 not taken.
1071 replay_step_comment(fmt::format("dmap={}", orig_destdmap));
6144 }
6145 8928 }
6146 35854 replay_step_comment_loadscr(screen);
6147
6148 // Reset the rngs and frame count so that recording steps can be modified without impacting
6149 // behavior of later screens.
6150 35854 replay_sync_rng();
6151 35854 }
6152
6153
2/2
✓ Branch 0 taken 1707536 times.
✓ Branch 1 taken 35854 times.
1743390 for (auto& state : get_screen_states())
6154 1707536 state.second.triggered_secrets = false;
6155 35854 slopes.clear();
6156 35854 Hero.clear_platform_ffc();
6157 35854 timeExitAllGenscript(GENSCR_ST_CHANGE_SCREEN);
6158 35854 clear_darkroom_bitmaps();
6159 35854 msgscr = nullptr;
6160
6161
2/2
✓ Branch 0 taken 50391860 times.
✓ Branch 1 taken 35854 times.
50427714 for (word x=0; x<animated_combos; x++)
6162 {
6163
2/2
✓ Branch 0 taken 20919990 times.
✓ Branch 1 taken 29471870 times.
50391860 if(combobuf[animated_combo_table4[x][0]].nextcombo!=0)
6164 {
6165 20919990 combobuf[animated_combo_table4[x][0]].aclk = 0;
6166 20919990 }
6167 50391860 }
6168 35854 reset_combo_animations2();
6169 35854 region_is_lit = false;
6170
6171 // Legacy features (combo and ffc overlays) may need the previous origin screens during loading
6172 // of the new ones.
6173 35854 bool origin_ffc_overlay = false;
6174
2/2
✓ Branch 0 taken 34717 times.
✓ Branch 1 taken 1137 times.
35854 if (origin_scr)
6175 {
6176
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 34715 times.
34717 if (!(origin_scr->flags5&fNOFFCARRYOVER))
6177 {
6178 34715 int c = origin_scr->numFFC();
6179
2/2
✓ Branch 0 taken 34571 times.
✓ Branch 1 taken 1038879 times.
1073450 for (int i = 0; i < c; i++)
6180 {
6181
2/2
✓ Branch 0 taken 1038735 times.
✓ Branch 1 taken 144 times.
1038879 if (origin_scr->ffcs[i].flags&ffc_carryover)
6182 {
6183 144 origin_ffc_overlay = true;
6184 144 break;
6185 }
6186 1038735 }
6187 34715 }
6188
6189
3/4
✓ Branch 0 taken 34717 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 144 times.
✓ Branch 3 taken 34573 times.
34717 if (origin_screen_overlay || origin_ffc_overlay)
6190 {
6191
2/2
✓ Branch 0 taken 1008 times.
✓ Branch 1 taken 144 times.
1152 for (int i = 0; i <= 6; i++)
6192 {
6193 1008 mapscr* prev_scr = get_scr_layer(cur_screen, i);
6194
1/2
✓ Branch 0 taken 1008 times.
✗ Branch 1 not taken.
1008 if (prev_scr)
6195 1008 prev_origin_scrs[i] = *prev_scr;
6196 else
6197 prev_origin_scrs[i] = {};
6198 1008 }
6199 144 }
6200 34717 }
6201
6202 // When loading a new screen, all previous FFC scripts end, with one exception.
6203 // Based on origin_ffc_overlay, some ffc scripts don't get reset. This set starts with all of
6204 // them, but scripts that need their data to persist will be removed.
6205 35854 loadscr_ffc_script_ids_to_remove.clear();
6206
2/2
✓ Branch 0 taken 74698175 times.
✓ Branch 1 taken 35854 times.
74734029 for (auto& key : scriptEngineDatas | std::views::keys)
6207 {
6208
2/2
✓ Branch 0 taken 73576270 times.
✓ Branch 1 taken 1121905 times.
74698175 if (key.first == ScriptType::FFC)
6209 1121905 loadscr_ffc_script_ids_to_remove.insert(key.second);
6210 }
6211
6212 35854 load_region(destdmap, screen);
6213
2/2
✓ Branch 0 taken 907 times.
✓ Branch 1 taken 34947 times.
35854 home_screen = screen >= 0x80 ? hero_screen : cur_screen;
6214 35854 hero_screen = screen;
6215
6216 35854 cpos_clear_all();
6217 35854 FFCore.destroyScriptableObjectsOfType(ScriptType::Screen);
6218 35854 FFCore.clear_combo_scripts();
6219
6220
2/2
✓ Branch 0 taken 164 times.
✓ Branch 1 taken 35690 times.
35854 if (is_in_scrolling_region())
6221 {
6222
2/2
✓ Branch 0 taken 20992 times.
✓ Branch 1 taken 164 times.
21156 for (int screen = 0; screen < 128; screen++)
6223 {
6224
2/2
✓ Branch 0 taken 19584 times.
✓ Branch 1 taken 1408 times.
20992 if (is_in_current_region(screen))
6225 {
6226
1/2
✓ Branch 0 taken 1408 times.
✗ Branch 1 not taken.
1408 bool screen_overlay = origin_screen_overlay && screen == cur_screen;
6227
1/2
✓ Branch 0 taken 1408 times.
✗ Branch 1 not taken.
1408 bool ffc_overlay = origin_ffc_overlay && screen == cur_screen;
6228 1408 load_a_screen_and_layers_init(destdmap, screen, ldir, screen_overlay, ffc_overlay);
6229 1408 }
6230 20992 }
6231 164 }
6232 else
6233 {
6234 35690 load_a_screen_and_layers_init(destdmap, screen, ldir, origin_screen_overlay, origin_ffc_overlay);
6235 }
6236
6237 35854 prepare_current_region_handles();
6238
6239
2/2
✓ Branch 0 taken 164 times.
✓ Branch 1 taken 35690 times.
35854 if (is_in_scrolling_region())
6240 {
6241
2/2
✓ Branch 0 taken 20992 times.
✓ Branch 1 taken 164 times.
21156 for (int screen = 0; screen < 128; screen++)
6242 {
6243
2/2
✓ Branch 0 taken 19584 times.
✓ Branch 1 taken 1408 times.
20992 if (is_in_current_region(screen))
6244 {
6245 1408 load_a_screen_and_layers_post(destdmap, screen, ldir);
6246 1408 }
6247 20992 }
6248 164 }
6249 else
6250 {
6251 35690 load_a_screen_and_layers_post(destdmap, screen, ldir);
6252 }
6253
6254 // If on a special screen, load the screen the player is currently on (home_screen) into special_warp_return_scr.
6255
2/2
✓ Branch 0 taken 34947 times.
✓ Branch 1 taken 907 times.
35854 if (screen >= 0x80)
6256
2/2
✓ Branch 0 taken 476 times.
✓ Branch 1 taken 431 times.
907 loadscr_old(orig_destdmap, home_screen, no_x80_dir ? -1 : ldir, origin_screen_overlay);
6257
6258 35854 update_slope_comboposes();
6259 35854 cpos_force_update();
6260 35854 trig_trigger_groups();
6261
6262
2/2
✓ Branch 0 taken 1121631 times.
✓ Branch 1 taken 35854 times.
1157485 for (int index : loadscr_ffc_script_ids_to_remove)
6263 {
6264 // Note: ideally would use "destroySprite", but during scrolling the previous
6265 // screen's FFCs are still accessible (even though only the new screen's FFC scripts run).
6266 // The only difference is a call to "release_sprite_owned_objects". To defer FFC script
6267 // owned objects being released until the end of the scroll, here "destroyScriptableObject"
6268 // is used instead.
6269 //
6270 // So when is "release_sprite_owned_objects" called for FFCs? For scrolling screen
6271 // transitions, it's at the end of "scrollscr" via "delete_temporary_screens". Otherwise,
6272 // it is called above when "load_region" calls "clear_temporary_screens".
6273 1121631 FFCore.destroyScriptableObject(ScriptType::FFC, index);
6274 }
6275
6276 // "extended height mode" includes the top 56 pixels as part of the visible mapscr viewport,
6277 // allowing for regions to display 4 more rows of combos (as many as ALTTP does). This part of
6278 // screen is normally reserved for the passive subscreen, but in this mode mapscr combos are drawn below it.
6279 // It is up to the quest designer to make their subscreen be actually transparent.
6280 //
6281 // When not in "extended height mode" (otherwise 56 is 0):
6282 // - playing_field_offset: 56, but changes during earthquakes
6283 // - original_playing_field_offset: always 56
6284 //
6285 // These values are used to adjust where things are drawn on screen to account for the passive subscreen. Examples:
6286 // - yofs of sprites
6287 // - bitmap y offsets in draw_screen
6288 // - drawing offsets for putscr, do_layer
6289 // - drawing offsets for various calls to overtile16 (see bomb weapon explosion)
6290 // - lots more
6291 //
6292 // TODO: consider refactor of yofs, make yofs start as 0 by default and add playing_field_offset at draw time?
6293
2/2
✓ Branch 0 taken 142 times.
✓ Branch 1 taken 35712 times.
35854 if (is_extended_height_mode())
6294 {
6295 142 playing_field_offset = 0;
6296 142 original_playing_field_offset = 0;
6297 // A few sprites exist as globals, so we must manually reset them.
6298 142 Hero.yofs = 0;
6299 142 mblock2.yofs = 0;
6300 142 }
6301 else
6302 {
6303 35712 mblock2.yofs = Hero.yofs = playing_field_offset = 56;
6304 35712 original_playing_field_offset = 56;
6305 }
6306 35854 is_any_room_dark = is_any_dark();
6307
6308 35854 game->load_portal();
6309 35854 throwGenScriptEvent(GENSCR_EVENT_CHANGE_SCREEN);
6310
3/4
✓ Branch 0 taken 35 times.
✓ Branch 1 taken 35819 times.
✓ Branch 2 taken 35 times.
✗ Branch 3 not taken.
35854 if (Hero.lift_wpn && get_qr(qr_CARRYABLE_NO_ACROSS_SCREEN))
6311 {
6312 delete Hero.lift_wpn;
6313 Hero.lift_wpn = nullptr;
6314 }
6315
6316 35854 enemy_spawning_has_checked_been_here = false;
6317 35854 markBmap(-1, hero_screen);
6318 35854 Hero.maybe_begin_advanced_maze();
6319 35854 }
6320
6321 // Don't use this directly! Use `loadscr` instead.
6322 907 void loadscr_old(int32_t destdmap, int32_t screen,int32_t ldir,bool overlay)
6323 {
6324
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 int32_t destlvl = DMaps[destdmap < 0 ? cur_dmap : destdmap].level;
6325
6326 907 mapscr previous_scr = *special_warp_return_scr;
6327 907 mapscr* scr = special_warp_return_scr;
6328
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 const mapscr* source = get_canonical_scr(cur_map, screen);
6329
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 *scr = *source;
6330
6331
2/2
✓ Branch 0 taken 5442 times.
✓ Branch 1 taken 907 times.
6349 for (int i = 1; i <= 6; i++)
6332 {
6333
2/2
✓ Branch 0 taken 383 times.
✓ Branch 1 taken 5059 times.
5442 if (scr->layermap[i-1] > 0)
6334
2/4
✓ Branch 0 taken 383 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 383 times.
✗ Branch 3 not taken.
383 special_warp_return_scrs[i] = *get_canonical_scr(scr->layermap[i-1] - 1, scr->layerscreen[i-1]);
6335 else
6336 5059 special_warp_return_scrs[i] = {};
6337 5442 }
6338
6339 907 scr->valid |= mVALID; //layer 0 is always valid
6340
6341
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 907 times.
907 if ( source->script > 0 )
6342 {
6343 scr->script = source->script;
6344 for ( int32_t q = 0; q < 8; q++ )
6345 {
6346 scr->screeninitd[q] = source->screeninitd[q];
6347 }
6348 FFCore.reset_script_engine_data(ScriptType::Screen, screen);
6349 }
6350 else
6351 {
6352 907 scr->script = 0;
6353 }
6354
6355
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 if(overlay)
6356 {
6357 for(int32_t c=0; c< 176; ++c)
6358 {
6359 if(scr->data[c]==0)
6360 {
6361 scr->data[c]=previous_scr.data[c];
6362 scr->sflag[c]=previous_scr.sflag[c];
6363 scr->cset[c]=previous_scr.cset[c];
6364 }
6365 }
6366
6367 for(int32_t i=0; i<6; i++)
6368 {
6369 if(previous_scr.layermap[i]>0 && scr->layermap[i]>0)
6370 {
6371 int32_t lm = (scr->layermap[i]-1)*MAPSCRS+scr->layerscreen[i];
6372 int32_t fm = (previous_scr.layermap[i]-1)*MAPSCRS+previous_scr.layerscreen[i];
6373
6374 for(int32_t c=0; c< 176; ++c)
6375 {
6376 if(TheMaps[lm].data[c]==0)
6377 {
6378 TheMaps[lm].data[c] = TheMaps[fm].data[c];
6379 TheMaps[lm].sflag[c] = TheMaps[fm].sflag[c];
6380 TheMaps[lm].cset[c] = TheMaps[fm].cset[c];
6381 }
6382 }
6383 }
6384 }
6385 }
6386
6387
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
29900 auto [offx, offy] = translate_screen_coordinates_to_world(screen);
6388
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 int c = scr->numFFC();
6389
2/2
✓ Branch 0 taken 907 times.
✓ Branch 1 taken 28993 times.
29900 for (word i = 0; i < c; i++)
6390 {
6391 28993 scr->ffcs[i].screen_spawned = screen;
6392
1/2
✓ Branch 0 taken 28993 times.
✗ Branch 1 not taken.
28993 scr->ffcs[i].x += offx;
6393
1/2
✓ Branch 0 taken 28993 times.
✗ Branch 1 not taken.
28993 scr->ffcs[i].y += offy;
6394 28993 }
6395
6396 907 int mi = mapind(cur_map, screen);
6397
6398 // Apply perm secrets, if applicable.
6399
3/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 536 times.
✓ Branch 3 taken 371 times.
907 if(canPermSecret(destdmap,screen))
6400 {
6401
3/4
✓ Branch 0 taken 536 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 204 times.
✓ Branch 3 taken 332 times.
536 if(game->maps[mi]&mSECRET) // if special stuff done before
6402 {
6403
1/2
✓ Branch 0 taken 204 times.
✗ Branch 1 not taken.
204 reveal_hidden_stairs(scr, screen, false);
6404
6405
1/2
✓ Branch 0 taken 204 times.
✗ Branch 1 not taken.
204 log_trigger_secret_reason(TriggerSource::SecretsScreenState);
6406
1/2
✓ Branch 0 taken 204 times.
✗ Branch 1 not taken.
204 get_screen_state(special_warp_return_scr->screen).triggered_secrets = true;
6407 204 bool do_replay_comment = true;
6408 204 bool from_active_screen = false;
6409
2/4
✓ Branch 0 taken 204 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 204 times.
✗ Branch 3 not taken.
204 trigger_secrets_for_screen_internal(create_screen_handles(special_warp_return_scr), from_active_screen, false, -1, do_replay_comment);
6410 204 }
6411
2/4
✓ Branch 0 taken 536 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 536 times.
✗ Branch 3 not taken.
536 if(game->maps[mi]&mLIGHTBEAM) // if special stuff done before
6412 {
6413 for (int layer = 0; layer <= 6; layer++)
6414 {
6415 mapscr* tscr = &special_warp_return_scrs[layer];
6416 for (int pos = 0; pos < 176; pos++)
6417 {
6418 newcombo const* cmb = &combobuf[tscr->data[pos]];
6419 if(cmb->type == cLIGHTTARGET)
6420 {
6421 if(!(cmb->usrflags&cflag1)) //Unlit version
6422 {
6423 tscr->data[pos] += 1;
6424 }
6425 }
6426 }
6427 }
6428 }
6429 536 }
6430
6431 screen_handles_t screen_handles;
6432
2/2
✓ Branch 0 taken 907 times.
✓ Branch 1 taken 6349 times.
7256 for (int i = 0; i <= 6; i++)
6433
3/4
✓ Branch 0 taken 6349 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1289 times.
✓ Branch 3 taken 5060 times.
6349 screen_handles[i] = {scr, special_warp_return_scrs[i].is_valid() ? &special_warp_return_scrs[i] : nullptr, screen, i};
6434
6435
2/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 907 times.
✗ Branch 3 not taken.
907 toggle_switches(game->lvlswitches[destlvl], true, screen_handles);
6436
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 toggle_gswitches_load(screen_handles);
6437
6438
3/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 902 times.
907 if(game->maps[mi]&mLOCKBLOCK) // if special stuff done before
6439 {
6440
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 remove_lockblocks(screen_handles);
6441 5 }
6442
6443
3/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 906 times.
907 if(game->maps[mi]&mBOSSLOCKBLOCK) // if special stuff done before
6444 {
6445
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 remove_bosslockblocks(screen_handles);
6446 1 }
6447
6448
2/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 907 times.
907 if(game->maps[mi]&mCHEST) // if special stuff done before
6449 {
6450 remove_chests(screen_handles);
6451 }
6452
6453
2/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 907 times.
907 if(game->maps[mi]&mLOCKEDCHEST) // if special stuff done before
6454 {
6455 remove_lockedchests(screen_handles);
6456 }
6457
6458
2/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 907 times.
907 if(game->maps[mi]&mBOSSCHEST) // if special stuff done before
6459 {
6460 remove_bosschests(screen_handles);
6461 }
6462
6463
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 clear_xdoors(screen_handles, true);
6464
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 clear_xstatecombos(screen_handles, true);
6465
6466 // check doors
6467
3/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 371 times.
✓ Branch 3 taken 536 times.
907 if (isdungeon(destdmap, screen))
6468 {
6469
2/2
✓ Branch 0 taken 1484 times.
✓ Branch 1 taken 371 times.
1855 for(int32_t i=0; i<4; i++)
6470 {
6471 1484 int32_t door=scr->door[i];
6472
6473
4/4
✓ Branch 0 taken 91 times.
✓ Branch 1 taken 9 times.
✓ Branch 2 taken 89 times.
✓ Branch 3 taken 1295 times.
1484 switch(door)
6474 {
6475 case d1WAYSHUTTER:
6476 case dSHUTTER:
6477
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1295 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1295 if ((ldir^1)==i && screen == home_screen)
6478 {
6479 scr->door[i]=dOPENSHUTTER;
6480 }
6481
6482
2/2
✓ Branch 0 taken 105 times.
✓ Branch 1 taken 1190 times.
1295 get_screen_state(screen).open_doors = -4;
6483 105 break;
6484
6485 case dLOCKED:
6486
3/4
✓ Branch 0 taken 91 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 80 times.
✓ Branch 3 taken 11 times.
91 if(game->maps[mi]&(mDOOR_UP<<i))
6487 {
6488 80 scr->door[i]=dUNLOCKED;
6489 80 }
6490
6491 91 break;
6492
6493 case dBOSS:
6494
3/4
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 4 times.
9 if(game->maps[mi]&(mDOOR_UP<<i))
6495 {
6496 5 scr->door[i]=dOPENBOSS;
6497 5 }
6498
6499 9 break;
6500
6501 case dBOMB:
6502
3/4
✓ Branch 0 taken 89 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 51 times.
✓ Branch 3 taken 38 times.
89 if(game->maps[mi]&(mDOOR_UP<<i))
6503 {
6504 51 scr->door[i]=dBOMBED;
6505 51 }
6506
6507 89 break;
6508 }
6509
6510
2/2
✓ Branch 0 taken 1484 times.
✓ Branch 1 taken 1190 times.
294 update_door(scr, i, scr->door[i]);
6511
6512
4/4
✓ Branch 0 taken 1390 times.
✓ Branch 1 taken 94 times.
✓ Branch 2 taken 11 times.
✓ Branch 3 taken 1379 times.
1484 if(door==dSHUTTER||door==d1WAYSHUTTER)
6513 {
6514 105 scr->door[i]=door;
6515 105 }
6516 1484 }
6517 371 }
6518
6519
2/2
✓ Branch 0 taken 6915 times.
✓ Branch 1 taken 549 times.
7256 for(int32_t j=-1; j<6; ++j) // j == -1 denotes the current screen
6520 {
6521
4/4
✓ Branch 0 taken 5442 times.
✓ Branch 1 taken 1473 times.
✓ Branch 2 taken 2763 times.
✓ Branch 3 taken 2679 times.
6915 if (j<0 || scr->layermap[j] > 0)
6522 {
6523
4/4
✓ Branch 0 taken 907 times.
✓ Branch 1 taken 383 times.
✓ Branch 2 taken 382 times.
✓ Branch 3 taken 1 times.
4236 mapscr *layerscreen= (j<0 ? scr : special_warp_return_scrs[j+1].valid ? &special_warp_return_scrs[j+1] :
6524 1 &TheMaps[(scr->layermap[j]-1)*MAPSCRS]+scr->layerscreen[j]);
6525
6526
2/2
✓ Branch 0 taken 224660 times.
✓ Branch 1 taken 3670 times.
228330 for(int32_t i=0; i<176; ++i)
6527 {
6528 224660 int32_t c=layerscreen->data[i];
6529
6530 // New screen flag: Cycle Combos At Screen Init
6531
5/8
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 224654 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 2380 times.
✓ Branch 7 taken 2380 times.
224660 if(combobuf[c].nextcombo != 0 && (scr->flags3 & fCYCLEONINIT) && (j<0 || get_qr(qr_CMBCYCLELAYERS)))
6532 {
6533 2380 int32_t r = 0;
6534
6535
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 2380 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
2380 while(combobuf[c].can_cycle() && r++ < 10)
6536 {
6537 newcombo const& cmb = combobuf[c];
6538 bool cycle_under = (cmb.animflags & AF_CYCLEUNDERCOMBO);
6539 auto cid = cycle_under ? layerscreen->undercombo : cmb.nextcombo;
6540 layerscreen->data[i] = cid;
6541 if(!(combobuf[c].animflags & AF_CYCLENOCSET))
6542 layerscreen->cset[i] = cycle_under ? layerscreen->undercset : cmb.nextcset;
6543 c = layerscreen->data[i];
6544 }
6545 }
6546 227040 }
6547 3670 }
6548 6349 }
6549 5309 }
6550
6551 // Load screen (and layers). Unlike loadscr, this doesn't load to the global temporary_screens, but
6552 // instead returns an array of mapscr.
6553 // Used to draw/save the map.
6554 45680 std::array<mapscr, 7> loadscr2(int32_t screen)
6555 {
6556 45680 std::array<mapscr, 7> scrs;
6557 45680 mapscr* scr = &scrs[0];
6558
6559
2/2
✓ Branch 0 taken 64716181 times.
✓ Branch 1 taken 45680 times.
64761861 for(word x=0; x<animated_combos; x++)
6560 {
6561
2/2
✓ Branch 0 taken 31963685 times.
✓ Branch 1 taken 32752496 times.
64716181 if(combobuf[animated_combo_table4[x][0]].nextcombo!=0)
6562 {
6563 32752496 combobuf[animated_combo_table4[x][0]].aclk=0;
6564 32752496 }
6565 64716181 }
6566
6567
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 const mapscr* source = get_canonical_scr(cur_map, screen);
6568
2/4
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 45680 times.
✗ Branch 3 not taken.
45680 if (!source->is_valid())
6569 {
6570 scrs[0].valid = 0;
6571 return scrs;
6572 }
6573
6574
2/4
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 45680 times.
✗ Branch 3 not taken.
45680 *scr = *get_canonical_scr(cur_map, screen);
6575
2/2
✓ Branch 0 taken 274080 times.
✓ Branch 1 taken 45680 times.
319760 for (int i = 1; i <= 6; i++)
6576 {
6577
2/2
✓ Branch 0 taken 64814 times.
✓ Branch 1 taken 209266 times.
274080 if (scr->layermap[i-1] > 0)
6578
2/4
✓ Branch 0 taken 64814 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 64814 times.
✗ Branch 3 not taken.
64814 scrs[i] = *get_canonical_scr(scr->layermap[i-1] - 1, scr->layerscreen[i-1]);
6579 else
6580 209266 scrs[i] = {};
6581 274080 }
6582
6583 screen_handles_t screen_handles;
6584
2/2
✓ Branch 0 taken 45680 times.
✓ Branch 1 taken 319760 times.
365440 for (int i = 0; i < 7; i++)
6585
3/4
✓ Branch 0 taken 319760 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 103790 times.
✓ Branch 3 taken 215970 times.
319760 screen_handles[i] = {scr, scrs[i].is_valid() ? &scrs[i] : nullptr, screen, i};
6586
6587 45680 int mi = mapind(cur_map, screen);
6588
6589
3/4
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 45626 times.
✓ Branch 3 taken 54 times.
45680 if(canPermSecret(-1,screen))
6590 {
6591
3/4
✓ Branch 0 taken 45626 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5730 times.
✓ Branch 3 taken 39896 times.
45626 if(game->maps[mi]&mSECRET) // if special stuff done before
6592 {
6593
1/2
✓ Branch 0 taken 5730 times.
✗ Branch 1 not taken.
5730 reveal_hidden_stairs(scr, screen, false);
6594 5730 bool from_active_screen = false;
6595 5730 bool do_replay_comment = true;
6596
1/2
✓ Branch 0 taken 5730 times.
✗ Branch 1 not taken.
5730 trigger_secrets_for_screen_internal(screen_handles, from_active_screen, false, -1, do_replay_comment);
6597 5730 }
6598
3/4
✓ Branch 0 taken 45626 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 45609 times.
✓ Branch 3 taken 17 times.
45626 if(game->maps[mi]&mLIGHTBEAM) // if special stuff done before
6599 {
6600
2/2
✓ Branch 0 taken 119 times.
✓ Branch 1 taken 17 times.
136 for (int layer = 0; layer <= 6; layer++)
6601 {
6602 119 mapscr* tscr = &scrs[layer];
6603
2/2
✓ Branch 0 taken 20944 times.
✓ Branch 1 taken 119 times.
21063 for (int pos = 0; pos < 176; pos++)
6604 {
6605 20944 newcombo const* cmb = &combobuf[tscr->data[pos]];
6606
2/2
✓ Branch 0 taken 20927 times.
✓ Branch 1 taken 17 times.
20944 if(cmb->type == cLIGHTTARGET)
6607 {
6608
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 17 times.
17 if(!(cmb->usrflags&cflag1)) //Unlit version
6609 {
6610 17 tscr->data[pos] += 1;
6611 17 }
6612 17 }
6613 20944 }
6614 119 }
6615 17 }
6616 45626 }
6617
6618
3/4
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 233 times.
✓ Branch 3 taken 45447 times.
45680 if(game->maps[mi]&mLOCKBLOCK) // if special stuff done before
6619 {
6620
1/2
✓ Branch 0 taken 233 times.
✗ Branch 1 not taken.
233 remove_lockblocks(screen_handles);
6621 233 }
6622
6623
3/4
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 45679 times.
45680 if(game->maps[mi]&mBOSSLOCKBLOCK) // if special stuff done before
6624 {
6625
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 remove_bosslockblocks(screen_handles);
6626 1 }
6627
6628
3/4
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 101 times.
✓ Branch 3 taken 45579 times.
45680 if(game->maps[mi]&mCHEST) // if special stuff done before
6629 {
6630
1/2
✓ Branch 0 taken 101 times.
✗ Branch 1 not taken.
101 remove_chests(screen_handles);
6631 101 }
6632
6633
3/4
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 24 times.
✓ Branch 3 taken 45656 times.
45680 if(game->maps[mi]&mLOCKEDCHEST) // if special stuff done before
6634 {
6635
1/2
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
24 remove_lockedchests(screen_handles);
6636 24 }
6637
6638
2/4
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 45680 times.
45680 if(game->maps[mi]&mBOSSCHEST) // if special stuff done before
6639 {
6640 remove_bosschests(screen_handles);
6641 }
6642
6643
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 clear_xdoors(screen_handles);
6644
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 clear_xstatecombos(screen_handles);
6645
6646 // check doors
6647
3/4
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 54 times.
✓ Branch 3 taken 45626 times.
45680 if (isdungeon(screen))
6648 {
6649
2/2
✓ Branch 0 taken 216 times.
✓ Branch 1 taken 54 times.
270 for(int32_t i=0; i<4; i++)
6650 {
6651 216 int32_t door=scr->door[i];
6652 216 bool putit=true;
6653
6654
4/5
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 61 times.
✓ Branch 4 taken 139 times.
216 switch(door)
6655 {
6656 case d1WAYSHUTTER:
6657 case dSHUTTER:
6658 61 break;
6659
6660 case dLOCKED:
6661
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 12 times.
12 if(game->maps[mi]&(mDOOR_UP<<i))
6662 {
6663 12 scr->door[i]=dUNLOCKED;
6664 12 }
6665
6666 12 break;
6667
6668 case dBOSS:
6669
2/4
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
4 if(game->maps[mi]&(mDOOR_UP<<i))
6670 {
6671 scr->door[i]=dOPENBOSS;
6672 }
6673
6674 4 break;
6675
6676 case dBOMB:
6677 if(game->maps[mi]&(mDOOR_UP<<i))
6678 {
6679 scr->door[i]=dBOMBED;
6680 }
6681
6682 break;
6683 }
6684
6685
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 216 times.
216 if(putit)
6686 {
6687
1/2
✓ Branch 0 taken 216 times.
✗ Branch 1 not taken.
216 putdoor(scr, scrollbuf, i, scr->door[i], false);
6688 216 }
6689
6690
3/4
✓ Branch 0 taken 155 times.
✓ Branch 1 taken 61 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 155 times.
216 if(door==dSHUTTER||door==d1WAYSHUTTER)
6691 {
6692 61 scr->door[i]=door;
6693 61 }
6694 216 }
6695 54 }
6696
6697
2/2
✓ Branch 0 taken 319760 times.
✓ Branch 1 taken 45680 times.
365440 for(int32_t j=-1; j<6; ++j) // j == -1 denotes the current screen
6698 {
6699
4/4
✓ Branch 0 taken 274080 times.
✓ Branch 1 taken 45680 times.
✓ Branch 2 taken 64814 times.
✓ Branch 3 taken 209266 times.
319760 if (j < 0 || scr->layermap[j] > 0)
6700 {
6701
2/2
✓ Branch 0 taken 64814 times.
✓ Branch 1 taken 45680 times.
110494 mapscr *layerscreen= (j<0 ? scr
6702 64814 : &(TheMaps[(scr->layermap[j]-1)*MAPSCRS+scr->layerscreen[j]]));
6703
6704
2/2
✓ Branch 0 taken 19446944 times.
✓ Branch 1 taken 110494 times.
19557438 for(int32_t i=0; i<176; ++i)
6705 {
6706 19446944 int32_t c=layerscreen->data[i];
6707
6708 // New screen flag: Cycle Combos At Screen Init
6709
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 19446944 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
19446944 if((scr->flags3 & fCYCLEONINIT) && (j<0 || get_qr(qr_CMBCYCLELAYERS)))
6710 {
6711 int32_t r = 0;
6712
6713 while(combobuf[c].can_cycle() && r++ < 10)
6714 {
6715 newcombo const& cmb = combobuf[c];
6716 bool cycle_under = (cmb.animflags & AF_CYCLEUNDERCOMBO);
6717 auto cid = cycle_under ? layerscreen->undercombo : cmb.nextcombo;
6718 layerscreen->data[i] = cid;
6719 if(!(combobuf[c].animflags & AF_CYCLENOCSET))
6720 layerscreen->cset[i] = cycle_under ? layerscreen->undercset : cmb.nextcset;
6721 c = layerscreen->data[i];
6722 }
6723 }
6724 19446944 }
6725 110494 }
6726 319760 }
6727
6728 45680 return scrs;
6729
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 }
6730
6731 19016051 void putscr(mapscr* scr, BITMAP* dest, int32_t x, int32_t y)
6732 {
6733 // This is a bogus value while screenscrolling == true, but that's ok
6734 // because it is only used to calculate the rpos, and during screenscrolling
6735 // only the modulus to get pos (draw_cmb_pos does RPOS_TO_POS) is needed, which
6736 // is always the same no matter the value of scr.
6737 19016051 int screen = get_screen_for_world_xy(x, y);
6738
6739 19016051 x -= viewport.x;
6740 19016051 y -= viewport.y;
6741
6742
3/6
✓ Branch 0 taken 19016051 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 19016051 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 19016051 times.
19016051 if (!scr->is_valid()||!show_layers[0]||scr->hidelayers & 1)
6743 {
6744 rectfill(dest,x,y,x+255,y+175,0);
6745 return;
6746 }
6747
6748 37903193 bool over = XOR(scr->flags7&fLAYER2BG,DMaps[cur_dmap].flags&dmfLAYER2BG)
6749
2/2
✓ Branch 0 taken 128909 times.
✓ Branch 1 taken 18887142 times.
19016051 || XOR(scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG);
6750
6751 int start_x, end_x, start_y, end_y;
6752 19016051 get_bounds_for_draw_cmb_calls(dest, x, y, start_x, end_x, start_y, end_y);
6753
2/2
✓ Branch 0 taken 19016051 times.
✓ Branch 1 taken 202549048 times.
221565099 for (int cy = start_y; cy < end_y; cy++)
6754 {
6755
2/2
✓ Branch 0 taken 3075834962 times.
✓ Branch 1 taken 202549048 times.
3278384010 for (int cx = start_x; cx < end_x; cx++)
6756 {
6757 3075834962 int i = cx + cy*16;
6758
2/2
✓ Branch 0 taken 357850966 times.
✓ Branch 1 taken 2717983996 times.
3075834962 auto rpos = screenscrolling ? rpos_t::None : POS_TO_RPOS(i, screen);
6759 3075834962 draw_cmb_pos(dest, x + cx*16, y + cy*16, rpos, scr->data[i], scr->cset[i], 0, over, false);
6760 3075834962 }
6761 202549048 }
6762 19016051 }
6763
6764 15539765 static void putscrdoors(const nearby_screens_t& nearby_screens, BITMAP *dest, int32_t x, int32_t y)
6765 {
6766
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15539765 times.
15539765 if (!show_layers[0])
6767 {
6768 return;
6769 }
6770
6771 15539765 x -= viewport.x;
6772 15539765 y -= viewport.y;
6773
6774
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15539765 times.
31215848 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
6775 15676083 mapscr* scr = screen_handles[0].base_scr;
6776
1/2
✓ Branch 0 taken 15676083 times.
✗ Branch 1 not taken.
15676083 if (!scr->is_valid())
6777 return;
6778
6779
2/2
✓ Branch 0 taken 123411 times.
✓ Branch 1 taken 15552672 times.
15676083 if(scr->door[0]==dBOMBED)
6780 {
6781 123411 over_door(scr, dest, 39, up, offx+x, offy+y);
6782 123411 }
6783
6784
2/2
✓ Branch 0 taken 143109 times.
✓ Branch 1 taken 15532974 times.
15676083 if(scr->door[1]==dBOMBED)
6785 {
6786 143109 over_door(scr, dest, 135, down, offx+x, offy+y);
6787 143109 }
6788
6789
2/2
✓ Branch 0 taken 155862 times.
✓ Branch 1 taken 15520221 times.
15676083 if(scr->door[2]==dBOMBED)
6790 {
6791 155862 over_door(scr, dest, 66, left, offx+x, offy+y);
6792 155862 }
6793
6794
2/2
✓ Branch 0 taken 132289 times.
✓ Branch 1 taken 15543794 times.
15676083 if(scr->door[3]==dBOMBED)
6795 {
6796 132289 over_door(scr, dest, 77, right, offx+x, offy+y);
6797 132289 }
6798 15676083 });
6799 15539765 }
6800
6801 3339968 void putscrdoors(mapscr* scr, BITMAP *dest, int32_t x, int32_t y)
6802 {
6803
2/4
✓ Branch 0 taken 3339968 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3339968 times.
✗ Branch 3 not taken.
3339968 if (!scr->is_valid() || !show_layers[0])
6804 return;
6805
6806 3339968 x -= viewport.x;
6807 3339968 y -= viewport.y;
6808
6809
2/2
✓ Branch 0 taken 37656 times.
✓ Branch 1 taken 3302312 times.
3339968 if(scr->door[0]==dBOMBED)
6810 {
6811 37656 over_door(scr,dest,39,up,x,y);
6812 37656 }
6813
6814
2/2
✓ Branch 0 taken 36495 times.
✓ Branch 1 taken 3303473 times.
3339968 if(scr->door[1]==dBOMBED)
6815 {
6816 36495 over_door(scr,dest,135,down,x,y);
6817 36495 }
6818
6819
2/2
✓ Branch 0 taken 40440 times.
✓ Branch 1 taken 3299528 times.
3339968 if(scr->door[2]==dBOMBED)
6820 {
6821 40440 over_door(scr,dest,66,left,x,y);
6822 40440 }
6823
6824
2/2
✓ Branch 0 taken 37063 times.
✓ Branch 1 taken 3302905 times.
3339968 if(scr->door[3]==dBOMBED)
6825 {
6826 37063 over_door(scr,dest,77,right,x,y);
6827 37063 }
6828 3339968 }
6829 232437410 static inline bool standing_on_z(newcombo const& cmb, zfix const& standing_z_state)
6830 {
6831 232437410 zfix cmb_z, cmb_z_step;
6832
4/4
✓ Branch 0 taken 92789 times.
✓ Branch 1 taken 232344621 times.
✓ Branch 2 taken 88819 times.
✓ Branch 3 taken 3970 times.
232437410 if(cmb.type == cCSWITCHBLOCK && (cmb.usrflags & cflag9))
6833 {
6834 3970 cmb_z = zslongToFix(cmb.attributes[2]);
6835
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3970 times.
3970 cmb_z_step = zslongToFix(zc_max(0,cmb.attributes[3]));
6836 3970 }
6837
2/2
✓ Branch 0 taken 1983 times.
✓ Branch 1 taken 232431457 times.
232433440 else if(cmb.genflags & cflag3)
6838 {
6839 1983 cmb_z = cmb.z_height;
6840
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1983 times.
1983 cmb_z_step = zc_max(0_zf,cmb.z_step_height);
6841 1983 }
6842 232431457 else return false;
6843
6844
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 5953 times.
✓ Branch 2 taken 4804 times.
✓ Branch 3 taken 1149 times.
5953 return (standing_z_state < 0 || (cmb_z>0 && (cmb_z - cmb_z_step) <= standing_z_state));
6845 232437410 }
6846 56117558 bool _walkflag(zfix_round zx,zfix_round zy,int32_t cnt)
6847 {
6848 56117558 return _walkflag(zx,zy,cnt,0_zf);
6849 }
6850
6851 132920561 bool _walkflag_new(const mapscr* s0, const mapscr* s1, const mapscr* s2, zfix_round zx, zfix_round zy, zfix const& standing_z_state, bool is_temp_screens)
6852 {
6853 132920561 int x = zx.getRound(), y = zy.getRound();
6854 132920561 int pos = COMBOPOS(x % 256, y % 176);
6855 132920561 const newcombo& c = combobuf[s0->data[pos]];
6856 132920561 const newcombo& c1 = combobuf[s1->data[pos]];
6857 132920561 const newcombo& c2 = combobuf[s2->data[pos]];
6858
4/4
✓ Branch 0 taken 130925120 times.
✓ Branch 1 taken 1995441 times.
✓ Branch 2 taken 130915660 times.
✓ Branch 3 taken 9460 times.
266043410 bool dried = (((iswater_type(c.type)) || (iswater_type(c1.type)) ||
6859
4/4
✓ Branch 0 taken 101153 times.
✓ Branch 1 taken 131016795 times.
✓ Branch 2 taken 2101809 times.
✓ Branch 3 taken 4245 times.
132920561 (iswater_type(c2.type))) && DRIEDLAKE);
6860 133122849 int32_t b=1;
6861
2/2
✓ Branch 0 taken 65628846 times.
✓ Branch 1 taken 67494003 times.
133122849 if(x&8) b<<=2;
6862
2/2
✓ Branch 0 taken 62187457 times.
✓ Branch 1 taken 70935392 times.
133122849 if(y&8) b<<=1;
6863
6864 133122849 int32_t cwalkflag = c.walk;
6865
4/4
✓ Branch 0 taken 133021705 times.
✓ Branch 1 taken 101144 times.
✓ Branch 2 taken 133021541 times.
✓ Branch 3 taken 164 times.
133122849 if(is_temp_screens && standing_on_z(c,standing_z_state)) cwalkflag &= (c.walk>>4)^0xF;
6866
8/10
✓ Branch 0 taken 50572 times.
✓ Branch 1 taken 133072113 times.
✓ Branch 2 taken 2096585 times.
✓ Branch 3 taken 2046013 times.
✓ Branch 4 taken 2096585 times.
✓ Branch 5 taken 133021541 times.
✓ Branch 6 taken 2096585 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 2096585 times.
✗ Branch 9 not taken.
133122685 else if ((c.type == cBRIDGE && get_qr(qr_OLD_BRIDGE_COMBOS)) || (iswater_type(c.type) && ((c.walk>>4)&b) && ((c.usrflags&cflag3) || (c.usrflags&cflag4)))) cwalkflag = 0;
6867
2/2
✓ Branch 0 taken 63476780 times.
✓ Branch 1 taken 69544925 times.
133021705 if (s1 != s0)
6868 {
6869
3/4
✓ Branch 0 taken 69544925 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 69544307 times.
✓ Branch 3 taken 618 times.
69544925 if(is_temp_screens && standing_on_z(c1,standing_z_state)) cwalkflag &= (c1.walk>>4)^0xF;
6870
4/10
✓ Branch 0 taken 11729 times.
✓ Branch 1 taken 69532578 times.
✓ Branch 2 taken 11729 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 11729 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
69544307 else if ((iswater_type(c1.type) && ((c1.walk>>4)&b) && get_qr(qr_WATER_ON_LAYER_1) && !((c1.usrflags&cflag3) || (c1.usrflags&cflag4)))) cwalkflag &= c1.walk;
6871
2/2
✓ Branch 0 taken 62906 times.
✓ Branch 1 taken 69481401 times.
69544307 else if (c1.type == cBRIDGE)
6872 {
6873
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 62906 times.
62906 if (!get_qr(qr_OLD_BRIDGE_COMBOS))
6874 {
6875 62906 int efflag = (c1.walk & 0xF0)>>4;
6876 62906 int newsolid = (c1.walk & 0xF);
6877 62906 cwalkflag = ((newsolid | cwalkflag) & (~efflag)) | (newsolid & efflag);
6878 62906 }
6879 else cwalkflag &= c1.walk;
6880 62906 }
6881
3/8
✓ Branch 0 taken 11729 times.
✓ Branch 1 taken 69469672 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 11729 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
69481401 else if ((iswater_type(c1.type) && get_qr(qr_WATER_ON_LAYER_1) && ((c1.usrflags&cflag3) || (c1.usrflags&cflag4)) && ((c1.walk>>4)&b))) cwalkflag = 0;
6882 69481401 else cwalkflag |= c1.walk;
6883 69544925 }
6884
2/2
✓ Branch 0 taken 103150925 times.
✓ Branch 1 taken 29870780 times.
133021705 if (s2 != s0)
6885 {
6886
2/4
✓ Branch 0 taken 29870780 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 29870780 times.
✗ Branch 3 not taken.
29870780 if(is_temp_screens && standing_on_z(c2,standing_z_state)) cwalkflag &= (c2.walk>>4)^0xF;
6887
4/10
✓ Branch 0 taken 2154 times.
✓ Branch 1 taken 29868626 times.
✓ Branch 2 taken 2154 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2154 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
29870780 else if ((iswater_type(c2.type) && ((c2.walk>>4)&b) && get_qr(qr_WATER_ON_LAYER_2) && !((c2.usrflags&cflag3) || (c2.usrflags&cflag4)))) cwalkflag &= c2.walk;
6888
2/2
✓ Branch 0 taken 4447 times.
✓ Branch 1 taken 29866333 times.
29870780 else if (c2.type == cBRIDGE)
6889 {
6890
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4447 times.
4447 if (!get_qr(qr_OLD_BRIDGE_COMBOS))
6891 {
6892 4447 int efflag = (c2.walk & 0xF0)>>4;
6893 4447 int newsolid = (c2.walk & 0xF);
6894 4447 cwalkflag = ((newsolid | cwalkflag) & (~efflag)) | (newsolid & efflag);
6895 4447 }
6896 else cwalkflag &= c2.walk;
6897 4447 }
6898
3/8
✓ Branch 0 taken 2154 times.
✓ Branch 1 taken 29864179 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2154 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
29866333 else if ((iswater_type(c2.type) && get_qr(qr_WATER_ON_LAYER_2) && ((c2.usrflags&cflag3) || (c2.usrflags&cflag4))) && ((c2.walk>>4)&b)) cwalkflag = 0;
6899 29866333 else cwalkflag |= c2.walk;
6900 29870780 }
6901
6902
4/4
✓ Branch 0 taken 29568194 times.
✓ Branch 1 taken 103453511 times.
✓ Branch 2 taken 948 times.
✓ Branch 3 taken 29567246 times.
133021705 if((cwalkflag&b) && !dried)
6903 29567246 return true;
6904
6905
3/4
✓ Branch 0 taken 103454459 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 103438048 times.
✓ Branch 3 taken 16411 times.
103454459 if (is_temp_screens && collide_object(zx, zy, 0.0001_zf, 0.0001_zf)) return true;
6906
6907 103438048 return false;
6908 133021705 }
6909
6910 // Returns true if the combo at viewport position x,y is solid. Looks at a combo's quadrant walkablity flags.
6911 133021705 static bool _walkflag_new(zfix_round zx, zfix_round zy, zfix const& standing_z_state)
6912 {
6913 133021705 int x = zx.getRound(), y = zy.getRound();
6914 133021705 mapscr* s0 = get_scr_for_world_xy_layer(x, y, 0);
6915 133021705 mapscr* s1 = get_scr_for_world_xy_layer(x, y, 1);
6916 133021705 mapscr* s2 = get_scr_for_world_xy_layer(x, y, 2);
6917
2/2
✓ Branch 0 taken 63476780 times.
✓ Branch 1 taken 69544925 times.
133021705 if (!s1->valid) s1 = s0;
6918
2/2
✓ Branch 0 taken 103150925 times.
✓ Branch 1 taken 29870780 times.
133021705 if (!s2->valid) s2 = s0;
6919 133021705 return _walkflag_new(s0, s1, s2, zx, zy, standing_z_state, true);
6920 }
6921
6922 128587954 bool _walkflag(zfix_round x,zfix_round y,int32_t cnt,zfix const& standing_z_state)
6923 {
6924 128587954 int max_x = world_w;
6925 128587954 int max_y = world_h;
6926
2/2
✓ Branch 0 taken 68545217 times.
✓ Branch 1 taken 60042737 times.
128587954 if (!get_qr(qr_LTTPWALK))
6927 {
6928 60042737 max_x -= 7;
6929 60042737 max_y -= 7;
6930 60042737 }
6931
4/4
✓ Branch 0 taken 128317122 times.
✓ Branch 1 taken 270832 times.
✓ Branch 2 taken 83268 times.
✓ Branch 3 taken 128233854 times.
128587954 if (x < 0 || y < 0) return false;
6932
2/2
✓ Branch 0 taken 322356 times.
✓ Branch 1 taken 127911498 times.
128233854 if (x >= max_x) return false;
6933
3/4
✓ Branch 0 taken 539663 times.
✓ Branch 1 taken 127371835 times.
✓ Branch 2 taken 539663 times.
✗ Branch 3 not taken.
127911498 if (x >= max_x - 8 && cnt == 2) return false;
6934
2/2
✓ Branch 0 taken 127362274 times.
✓ Branch 1 taken 549224 times.
127911498 if (y >= max_y) return false;
6935
6936
4/4
✓ Branch 0 taken 29465504 times.
✓ Branch 1 taken 97896770 times.
✓ Branch 2 taken 92237339 times.
✓ Branch 3 taken 5659431 times.
127362274 return _walkflag_new(x, y, standing_z_state) || (cnt != 1 && _walkflag_new(x + 8, y, standing_z_state));
6937 128587954 }
6938
6939 99143870 static bool effectflag(int32_t x, int32_t y, int32_t layer)
6940 {
6941 99143870 mapscr* s0 = get_scr_for_world_xy(x, y);
6942 99143870 mapscr* s1 = get_scr_for_world_xy_layer(x, y, 1);
6943 99143870 mapscr* s2 = get_scr_for_world_xy_layer(x, y, 2);
6944
2/2
✓ Branch 0 taken 51514522 times.
✓ Branch 1 taken 47629348 times.
99143870 if (!s1->valid) s1 = s0;
6945
2/2
✓ Branch 0 taken 17652787 times.
✓ Branch 1 taken 81491083 times.
99143870 if (!s2->valid) s2 = s0;
6946
6947 99143870 int pos = COMBOPOS(x % 256, y % 176);
6948 99143870 const newcombo& c = combobuf[s0->data[pos]];
6949 99143870 const newcombo& c1 = combobuf[s1->data[pos]];
6950 99143870 const newcombo& c2 = combobuf[s2->data[pos]];
6951
4/4
✓ Branch 0 taken 98216592 times.
✓ Branch 1 taken 927278 times.
✓ Branch 2 taken 98215226 times.
✓ Branch 3 taken 1366 times.
198287740 bool dried = (((iswater_type(c.type)) || (iswater_type(c1.type)) ||
6952
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 98215226 times.
✓ Branch 2 taken 926808 times.
✓ Branch 3 taken 1836 times.
99143870 (iswater_type(c2.type))) && DRIEDLAKE);
6953 99143870 int32_t b=1;
6954
2/2
✓ Branch 0 taken 49874789 times.
✓ Branch 1 taken 49269081 times.
99143870 if(x&8) b<<=2;
6955
2/2
✓ Branch 0 taken 41816616 times.
✓ Branch 1 taken 57327254 times.
99143870 if(y&8) b<<=1;
6956
6957 99143870 int32_t cwalkflag = (c.walk>>4);
6958
2/2
✓ Branch 0 taken 76350269 times.
✓ Branch 1 taken 22793601 times.
99143870 if (layer == 0) cwalkflag = (c1.walk>>4);
6959
2/2
✓ Branch 0 taken 76351467 times.
✓ Branch 1 taken 22792403 times.
99143870 if (layer == 1) cwalkflag = (c2.walk>>4);
6960 //if (c.type == cBRIDGE || (iswater_type(c.type) && ((c.usrflags&cflag3) || (c.usrflags&cflag4)))) cwalkflag = 0;
6961
4/4
✓ Branch 0 taken 51514522 times.
✓ Branch 1 taken 47629348 times.
✓ Branch 2 taken 22464483 times.
✓ Branch 3 taken 29050039 times.
99143870 if (s1 != s0 && layer < 0)
6962 {
6963
2/2
✓ Branch 0 taken 22451077 times.
✓ Branch 1 taken 13406 times.
22464483 if (c1.type == cBRIDGE) cwalkflag &= (~(c1.walk>>4));
6964 22464483 }
6965
4/4
✓ Branch 0 taken 17652787 times.
✓ Branch 1 taken 81491083 times.
✓ Branch 2 taken 13091910 times.
✓ Branch 3 taken 4560877 times.
99143870 if (s2 != s0 && layer < 1)
6966 {
6967
2/2
✓ Branch 0 taken 13086050 times.
✓ Branch 1 taken 5860 times.
13091910 if (c2.type == cBRIDGE) cwalkflag &= (~(c2.walk>>4));
6968 13091910 }
6969
6970
2/2
✓ Branch 0 taken 98984616 times.
✓ Branch 1 taken 159254 times.
99143870 return (cwalkflag&b) ? !dried : false;
6971 }
6972
6973 99518754 bool _effectflag(int32_t x,int32_t y,int32_t cnt, int32_t layer, bool notLink)
6974 {
6975 DCHECK(cnt == 0 || cnt == 1);
6976 99518754 int max_x = world_w;
6977 99518754 int max_y = world_h;
6978
3/4
✓ Branch 0 taken 45833723 times.
✓ Branch 1 taken 53685031 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 45833723 times.
99518754 if (!get_qr(qr_LTTPWALK) && !notLink)
6979 {
6980 45833723 max_x -= 7;
6981 45833723 max_y -= 7;
6982 45833723 }
6983
4/4
✓ Branch 0 taken 99518001 times.
✓ Branch 1 taken 753 times.
✓ Branch 2 taken 204 times.
✓ Branch 3 taken 99517797 times.
99518754 if (x < 0 || y < 0) return false;
6984
2/2
✓ Branch 0 taken 818 times.
✓ Branch 1 taken 99516979 times.
99517797 if (x >= max_x) return false;
6985
3/4
✓ Branch 0 taken 521780 times.
✓ Branch 1 taken 98995199 times.
✓ Branch 2 taken 521780 times.
✗ Branch 3 not taken.
99516979 if (x >= max_x - 8 && cnt == 2) return false;
6986
2/2
✓ Branch 0 taken 373109 times.
✓ Branch 1 taken 99143870 times.
99516979 if (y >= max_y) return false;
6987
6988
3/4
✓ Branch 0 taken 98983826 times.
✓ Branch 1 taken 160044 times.
✓ Branch 2 taken 160044 times.
✗ Branch 3 not taken.
99143870 return effectflag(x, y, layer) || (cnt == 2 && effectflag(x + 8, y, layer));
6989 99518754 }
6990
6991 // used by mapdata->isSolid(x,y) in ZScript
6992 bool _walkflag(zfix_round zx,zfix_round zy,int32_t cnt, mapscr* m)
6993 {
6994 int x = zx.getRound(), y = zy.getRound();
6995 {
6996 int max_x = 256;
6997 int max_y = 176;
6998 if (!get_qr(qr_LTTPWALK))
6999 {
7000 max_x -= 7;
7001 max_y -= 7;
7002 }
7003 if (x < 0 || y < 0) return false;
7004 if (x >= max_x) return false;
7005 if (x >= max_x - 8 && cnt == 2) return false;
7006 if (y >= max_y) return false;
7007 }
7008
7009 const mapscr *s1, *s2;
7010
7011 if ( m->layermap[0] > 0 )
7012 {
7013 s1 = get_canonical_scr(m->layermap[0], m->layerscreen[0]);
7014 }
7015 else s1 = m;
7016
7017 if ( m->layermap[1] > 0 )
7018 {
7019 s2 = get_canonical_scr(m->layermap[1], m->layerscreen[1]);
7020 }
7021 else s2 = m;
7022
7023 zfix unused;
7024 return _walkflag_new(m, s1, s2, x, y, unused, false) || (cnt != 1 && _walkflag_new(m, s1, s2, x + 8, y, unused, false));
7025 }
7026
7027 bool _walkflag_layer(zfix_round x, zfix_round y, int32_t layer, int32_t cnt)
7028 {
7029 DCHECK_LAYER_NEG1_INDEX(layer);
7030 mapscr* m = get_scr_for_world_xy_layer(x, y, layer + 1);
7031 if (!m->is_valid()) return false;
7032 return _walkflag_layer(x, y, cnt, m);
7033 }
7034
7035 static bool _walkflag_layer_new(zfix_round zx,zfix_round zy,int32_t cnt, mapscr* m, int max_x, int max_y)
7036 {
7037 int x = zx.getRound(), y = zy.getRound();
7038
7039 if (!get_qr(qr_LTTPWALK))
7040 {
7041 max_x -= 7;
7042 max_y -= 7;
7043 }
7044 if (x < 0 || y < 0) return false;
7045 if (x >= max_x) return false;
7046 if (x >= max_x - 8 && cnt == 2) return false;
7047 if (y >= max_y) return false;
7048
7049 if(!m) return true;
7050
7051 int pos = COMBOPOS(x%256, y%176);
7052 const newcombo* c = &combobuf[m->data[pos]];
7053 bool dried = ((iswater_type(c->type)) && DRIEDLAKE);
7054 int32_t b=1;
7055
7056 if(x&8) b<<=2;
7057
7058 if(y&8) b<<=1;
7059
7060 if((c->walk&b) && !dried)
7061 return true;
7062
7063 if(cnt==1) return false;
7064
7065 ++pos;
7066
7067 if(!(x&8))
7068 b<<=2;
7069 else
7070 {
7071 c = &combobuf[m->data[pos]];
7072 dried = ((iswater_type(c->type)) && DRIEDLAKE);
7073 b=1;
7074
7075 if(y&8) b<<=1;
7076 }
7077
7078 return (c->walk&b) ? !dried : false;
7079 }
7080
7081 //Only check the given mapscr*, not its layer 1&2
7082 bool _walkflag_layer(zfix_round zx,zfix_round zy,int32_t cnt, mapscr* m)
7083 {
7084 return _walkflag_layer_new(zx, zy, cnt, m, world_w, world_h);
7085 }
7086
7087 bool _walkflag_layer_scrolling(zfix_round zx,zfix_round zy,int32_t cnt, mapscr* m)
7088 {
7089 return _walkflag_layer_new(zx, zy, cnt, m, scrolling_region.width, scrolling_region.height);
7090 }
7091
7092 313446 bool _effectflag_layer(int32_t x, int32_t y, int32_t layer, int32_t cnt, bool notLink)
7093 {
7094 DCHECK_LAYER_NEG1_INDEX(layer);
7095 313446 mapscr* m = get_scr_for_world_xy_layer(x, y, layer + 1);
7096
2/2
✓ Branch 0 taken 1762 times.
✓ Branch 1 taken 311684 times.
313446 if (!m->is_valid()) return false;
7097 311684 return _effectflag_layer(x, y, cnt, m, notLink);
7098 313446 }
7099
7100 377717 bool _effectflag_layer(int32_t x,int32_t y,int32_t cnt, mapscr* m, bool notLink)
7101 {
7102 377717 int max_x = world_w;
7103 377717 int max_y = world_h;
7104
3/4
✓ Branch 0 taken 50002 times.
✓ Branch 1 taken 327715 times.
✓ Branch 2 taken 50002 times.
✗ Branch 3 not taken.
377717 if (!get_qr(qr_LTTPWALK) && !notLink)
7105 {
7106 max_x -= 7;
7107 max_y -= 7;
7108 }
7109
2/4
✓ Branch 0 taken 377717 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 377717 times.
377717 if (x < 0 || y < 0) return false;
7110
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 377717 times.
377717 if (x >= max_x) return false;
7111
3/4
✓ Branch 0 taken 1209 times.
✓ Branch 1 taken 376508 times.
✓ Branch 2 taken 1209 times.
✗ Branch 3 not taken.
377717 if (x >= max_x - 8 && cnt == 2) return false;
7112
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 377717 times.
377717 if (y >= max_y) return false;
7113
7114
1/2
✓ Branch 0 taken 377717 times.
✗ Branch 1 not taken.
377717 if (!m) return true;
7115
7116 377717 int pos = COMBOPOS(x%256, y%176);
7117 377717 const newcombo* c = &combobuf[m->data[pos]];
7118
3/4
✓ Branch 0 taken 377336 times.
✓ Branch 1 taken 381 times.
✓ Branch 2 taken 381 times.
✗ Branch 3 not taken.
378098 bool dried = ((iswater_type(c->type)) && DRIEDLAKE);
7119 377717 int32_t b=1;
7120
7121
2/2
✓ Branch 0 taken 205340 times.
✓ Branch 1 taken 172377 times.
377717 if(x&8) b<<=2;
7122
7123
2/2
✓ Branch 0 taken 157087 times.
✓ Branch 1 taken 220630 times.
377717 if(y&8) b<<=1;
7124
7125
3/4
✓ Branch 0 taken 308723 times.
✓ Branch 1 taken 68994 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 308723 times.
377717 if(((c->walk>>4)&b) && !dried)
7126 308723 return true;
7127
7128
1/2
✓ Branch 0 taken 68994 times.
✗ Branch 1 not taken.
68994 if(cnt==1) return false;
7129
7130 ++pos;
7131
7132 if(!(x&8))
7133 b<<=2;
7134 else
7135 {
7136 c = &combobuf[m->data[pos]];
7137 dried = ((iswater_type(c->type)) && DRIEDLAKE);
7138 b=1;
7139
7140 if(y&8) b<<=1;
7141 }
7142
7143 return ((c->walk>>4)&b) ? !dried : false;
7144 377717 }
7145
7146 812605 bool water_walkflag(int32_t x, int32_t y, int32_t cnt)
7147 {
7148 812605 int max_x = world_w;
7149 812605 int max_y = world_h;
7150
2/2
✓ Branch 0 taken 117367 times.
✓ Branch 1 taken 695238 times.
812605 if (!get_qr(qr_LTTPWALK))
7151 {
7152 695238 max_x -= 7;
7153 695238 max_y -= 7;
7154 695238 }
7155
2/4
✓ Branch 0 taken 812605 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 812605 times.
812605 if (x < 0 || y < 0) return false;
7156
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 812605 times.
812605 if (x >= max_x) return false;
7157
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 812605 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
812605 if (x >= max_x - 8 && cnt == 2) return false;
7158
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 812605 times.
812605 if (y >= max_y) return false;
7159
7160
3/4
✓ Branch 0 taken 16825 times.
✓ Branch 1 taken 795780 times.
✓ Branch 2 taken 795780 times.
✗ Branch 3 not taken.
812605 return water_walkflag(x, y) || (cnt != 1 && water_walkflag(x + 8, y));
7161 812605 }
7162
7163 812605 bool water_walkflag(int32_t x, int32_t y)
7164 {
7165 812605 const newcombo& c = combobuf[MAPCOMBO2(-1, x, y)];
7166 812605 const newcombo& c1 = combobuf[MAPCOMBO2(0, x, y)];
7167 812605 const newcombo& c2 = combobuf[MAPCOMBO2(1, x, y)];
7168
7169 812605 int32_t b=1;
7170
2/2
✓ Branch 0 taken 414677 times.
✓ Branch 1 taken 397928 times.
812605 if(x&8) b<<=2;
7171
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 812605 times.
812605 if(y&8) b<<=1;
7172
7173
2/2
✓ Branch 0 taken 26377 times.
✓ Branch 1 taken 786228 times.
812605 if(get_qr(qr_NO_SOLID_SWIM))
7174 {
7175
2/2
✓ Branch 0 taken 132 times.
✓ Branch 1 taken 26245 times.
26377 if(c.walk&b)
7176 132 return true;
7177
7178
2/2
✓ Branch 0 taken 292 times.
✓ Branch 1 taken 25953 times.
26245 if(c1.walk&b)
7179 292 return true;
7180
7181
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 25953 times.
25953 if(c2.walk&b)
7182 return true;
7183 25953 }
7184 else
7185 {
7186
4/4
✓ Branch 0 taken 36133 times.
✓ Branch 1 taken 750095 times.
✓ Branch 2 taken 19762 times.
✓ Branch 3 taken 16371 times.
786228 if((c.walk&b) && !iswater_type(c.type))
7187 16371 return true;
7188
7189
3/4
✓ Branch 0 taken 17 times.
✓ Branch 1 taken 769840 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 17 times.
769857 if((c1.walk&b) && !iswater_type(c1.type))
7190 17 return true;
7191
7192
3/4
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 769827 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 13 times.
769840 if((c2.walk&b) && !iswater_type(c2.type))
7193 13 return true;
7194 }
7195
7196 795780 return false;
7197 812605 }
7198
7199 564116 bool hit_walkflag(int32_t x,int32_t y,int32_t cnt)
7200 {
7201
2/2
✓ Branch 0 taken 90999 times.
✓ Branch 1 taken 473117 times.
564116 if(dlevel)
7202
8/8
✓ Branch 0 taken 471712 times.
✓ Branch 1 taken 1405 times.
✓ Branch 2 taken 468517 times.
✓ Branch 3 taken 3195 times.
✓ Branch 4 taken 466857 times.
✓ Branch 5 taken 1660 times.
✓ Branch 6 taken 4199 times.
✓ Branch 7 taken 462658 times.
473117 if(x<32 || y<40 || (x+(cnt-1)*8)>=world_w-32 || y>=world_h-32)
7203 10459 return true;
7204
7205
3/4
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 553655 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
553657 if(blockpath && y<((get_qr(qr_LTTPCOLLISION))?80:88))
7206 return true;
7207
7208
8/8
✓ Branch 0 taken 553388 times.
✓ Branch 1 taken 269 times.
✓ Branch 2 taken 553155 times.
✓ Branch 3 taken 233 times.
✓ Branch 4 taken 552946 times.
✓ Branch 5 taken 209 times.
✓ Branch 6 taken 346 times.
✓ Branch 7 taken 552600 times.
553657 if(x<16 || y<16 || (x+(cnt-1)*8)>=world_w-16 || y>=world_h-16)
7209 1057 return true;
7210
7211 // for(int32_t i=0; i<4; i++)
7212
4/4
✓ Branch 0 taken 841 times.
✓ Branch 1 taken 551759 times.
✓ Branch 2 taken 36 times.
✓ Branch 3 taken 805 times.
552600 if(mblock2.clk && mblock2.hit(x,y,0,cnt*8,1,16))
7213 36 return true;
7214
7215
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 552564 times.
552564 if (collide_object(x, y,cnt*8, 1))
7216 return true;
7217
7218 552564 return _walkflag(x,y,cnt);
7219 564116 }
7220
7221 12110 bool solpush_walkflag(int32_t x, int32_t y, int32_t cnt, solid_object const* ign)
7222 {
7223 // 16 pixel buffer to account for slopes that are on bordering screens.
7224
4/8
✓ Branch 0 taken 12110 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12110 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 12110 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 12110 times.
12110 if(x<0 || y<0 || x>=world_w+16 || y>=world_h+16)
7225 return true;
7226
7227 // for(int32_t i=0; i<4; i++)
7228
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 12110 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12110 if(mblock2.clk && mblock2.hit(x,y,0,cnt*8,1,16))
7229 return true;
7230
7231
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12110 times.
12110 if (collide_object(x, y,cnt*8, 1, ign))
7232 return true;
7233
7234 12110 return _walkflag(x,y,cnt);
7235 12110 }
7236
7237 37837 void map_bkgsfx(bool on)
7238 {
7239
2/2
✓ Branch 0 taken 37816 times.
✓ Branch 1 taken 21 times.
37837 if(on)
7240 {
7241 37816 cont_sfx(hero_scr->oceansfx);
7242
7243
4/4
✓ Branch 0 taken 369 times.
✓ Branch 1 taken 37447 times.
✓ Branch 2 taken 315 times.
✓ Branch 3 taken 54 times.
37816 if(hero_scr->bosssfx && !(game->lvlitems[dlevel]&liBOSS))
7244 315 cont_sfx(hero_scr->bosssfx);
7245 37816 }
7246 else
7247 {
7248 21 adjust_sfx(hero_scr->oceansfx,128,false);
7249 21 adjust_sfx(hero_scr->bosssfx,128,false);
7250
7251
2/2
✓ Branch 0 taken 114 times.
✓ Branch 1 taken 21 times.
135 for(int32_t i=0; i<guys.Count(); i++)
7252 {
7253
2/2
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 84 times.
114 if(((enemy*)guys.spr(i))->bgsfx)
7254 84 stop_sfx(((enemy*)guys.spr(i))->bgsfx);
7255 114 }
7256 }
7257 37837 }
7258
7259 239 void toggle_switches(dword flags, bool entry)
7260 {
7261
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 239 times.
239 if(!flags) return; //No flags to toggle
7262
7263 478 for_every_base_screen_in_region([&](mapscr* scr, unsigned int region_scr_x, unsigned int region_scr_y) {
7264 239 toggle_switches(flags, entry, create_screen_handles(scr));
7265 239 });
7266 239 }
7267 54044 void toggle_switches(dword flags, bool entry, const screen_handles_t& screen_handles)
7268 {
7269
2/2
✓ Branch 0 taken 737 times.
✓ Branch 1 taken 53307 times.
54044 if(!flags) return; //No flags to toggle
7270
7271 737 mapscr* m = screen_handles[0].base_scr;
7272 737 int screen = m->screen;
7273 737 bool is_active_screen = is_in_current_region(m);
7274
7275 305041 for_every_rpos_in_screen(screen_handles, [&](const rpos_handle_t& rpos_handle) {
7276 304304 byte togglegrid[176] = {0};
7277 304304 mapscr* scr = rpos_handle.scr;
7278 304304 int lyr = rpos_handle.layer;
7279 304304 int pos = rpos_handle.pos;
7280 304304 newcombo const& cmb = combobuf[scr->data[pos]];
7281
2/2
✓ Branch 0 taken 39424 times.
✓ Branch 1 taken 264880 times.
304304 if(is_active_screen)
7282
1/2
✓ Branch 0 taken 264880 times.
✗ Branch 1 not taken.
367773 trig_each_combo_trigger(rpos_handle, [&](combo_trigger const& trig){
7283
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 102893 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
102893 return trig.trigger_flags.get(TRIGFLAG_TRIGLEVELSTATE) && trig.trig_lstate < 32 && (flags&(1<<trig.trig_lstate));
7284 }, ctrigSWITCHSTATE);
7285
3/4
✓ Branch 0 taken 303641 times.
✓ Branch 1 taken 663 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2760 times.
304304 if((cmb.type == cCSWITCH || cmb.type == cCSWITCHBLOCK) && cmb.attribytes[0] < 32
7286
2/2
✓ Branch 0 taken 2760 times.
✓ Branch 1 taken 301544 times.
304304 && !(cmb.usrflags & cflag11)) //global state
7287 {
7288
2/2
✓ Branch 0 taken 446 times.
✓ Branch 1 taken 2314 times.
2760 if(flags&(1<<cmb.attribytes[0]))
7289 {
7290 2314 set<int32_t> oldData;
7291 //Increment the combo/cset by the attributes
7292 2314 int32_t cmbofs = (cmb.attributes[0]/10000L);
7293 2314 int32_t csofs = (cmb.attributes[1]/10000L);
7294
1/2
✓ Branch 0 taken 2314 times.
✗ Branch 1 not taken.
2314 oldData.insert(scr->data[pos]);
7295
1/2
✓ Branch 0 taken 2314 times.
✗ Branch 1 not taken.
2314 scr->data[pos] = BOUND_COMBO(scr->data[pos] + cmbofs);
7296 2314 scr->cset[pos] = (scr->cset[pos] + csofs) & 15;
7297
4/4
✓ Branch 0 taken 1435 times.
✓ Branch 1 taken 879 times.
✓ Branch 2 taken 1197 times.
✓ Branch 3 taken 238 times.
2314 if(entry && (cmb.usrflags&cflag8))
7298 {
7299 238 newcombo const* tmp = &combobuf[scr->data[pos]];
7300
2/4
✓ Branch 0 taken 238 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 238 times.
✗ Branch 3 not taken.
238 while(tmp->can_cycle())
7301 {
7302 bool cycle_under = (tmp->animflags & AF_CYCLEUNDERCOMBO);
7303 auto cid = cycle_under ? scr->undercombo : tmp->nextcombo;
7304 if(oldData.find(cid) != oldData.end())
7305 break;
7306
7307 scr->data[pos] = cid;
7308 if(!(tmp->animflags & AF_CYCLENOCSET))
7309 scr->cset[pos] = cycle_under ? scr->undercset : tmp->nextcset;
7310 oldData.insert(cid);
7311 tmp = &combobuf[cid];
7312 }
7313 238 }
7314 2314 int32_t cmbid = scr->data[pos];
7315
2/2
✓ Branch 0 taken 41 times.
✓ Branch 1 taken 2273 times.
2314 if(combobuf[cmbid].animflags & AF_CYCLE)
7316 {
7317 41 combobuf[cmbid].tile = combobuf[cmbid].o_tile;
7318 41 combobuf[cmbid].cur_frame=0;
7319 41 combobuf[cmbid].aclk = 0;
7320
1/2
✓ Branch 0 taken 41 times.
✗ Branch 1 not taken.
41 combo_caches::drawing.refresh(cmbid);
7321 41 }
7322 2314 togglegrid[pos] |= (1<<lyr); //Mark this pos toggled for this layer
7323
2/2
✓ Branch 0 taken 511 times.
✓ Branch 1 taken 1803 times.
2314 if(cmb.type == cCSWITCH) return; //Switches don't toggle other layers
7324
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2147 times.
2147 for(int32_t lyr2 = 0; lyr2 < 7; ++lyr2) //Toggle same pos on other layers, if flag set
7325 {
7326
2/2
✓ Branch 0 taken 1671 times.
✓ Branch 1 taken 476 times.
2147 if(lyr==lyr2) return;
7327
2/2
✓ Branch 0 taken 132 times.
✓ Branch 1 taken 344 times.
476 if(!(cmb.usrflags&(1<<lyr2))) return;
7328
1/2
✓ Branch 0 taken 344 times.
✗ Branch 1 not taken.
344 if(togglegrid[pos]&(1<<lyr2)) return;
7329
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 344 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
344 mapscr* scr_2 = (lyr2 ? get_scr_layer(screen, lyr2) : m);
7330
1/2
✓ Branch 0 taken 344 times.
✗ Branch 1 not taken.
344 if(!scr_2->data[pos]) //Don't increment empty space
7331 return;
7332 344 newcombo const& cmb_2 = combobuf[scr_2->data[pos]];
7333
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 344 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
344 if(lyr2 > lyr && (cmb_2.type == cCSWITCH || cmb_2.type == cCSWITCHBLOCK) && !(cmb.usrflags & cflag11)
7334 && cmb_2.attribytes[0] < 32 && (flags&(1<<cmb_2.attribytes[0])))
7335 return; //This is a switch/block that will be hit later in the loop!
7336 344 set<int32_t> oldData2;
7337 //Increment the combo/cset by the original cmb's attributes
7338
1/2
✓ Branch 0 taken 344 times.
✗ Branch 1 not taken.
344 oldData2.insert(scr_2->data[pos]);
7339
1/2
✓ Branch 0 taken 344 times.
✗ Branch 1 not taken.
344 scr_2->data[pos] = BOUND_COMBO(scr_2->data[pos] + cmbofs);
7340 344 scr_2->cset[pos] = (scr_2->cset[pos] + csofs) & 15;
7341
3/4
✓ Branch 0 taken 50 times.
✓ Branch 1 taken 294 times.
✓ Branch 2 taken 50 times.
✗ Branch 3 not taken.
344 if(entry && (cmb.usrflags&cflag8)) //Skip cycling on screen entry
7342 {
7343 newcombo const* tmp = &combobuf[scr_2->data[pos]];
7344 while(tmp->can_cycle())
7345 {
7346 bool cycle_under = (tmp->animflags & AF_CYCLEUNDERCOMBO);
7347 auto cid = cycle_under ? scr_2->undercombo : tmp->nextcombo;
7348 if(oldData2.find(cid) != oldData2.end())
7349 break;
7350
7351 scr_2->data[pos] = cid;
7352 if(!(tmp->animflags & AF_CYCLENOCSET))
7353 scr_2->cset[pos] = cycle_under ? scr_2->undercset : tmp->nextcset;
7354 oldData2.insert(cid);
7355 tmp = &combobuf[cid];
7356 }
7357 }
7358 344 int32_t cmbid2 = scr_2->data[pos];
7359
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 344 times.
344 if(combobuf[cmbid2].animflags & AF_CYCLE)
7360 {
7361 combobuf[cmbid2].tile = combobuf[cmbid2].o_tile;
7362 combobuf[cmbid2].cur_frame=0;
7363 combobuf[cmbid2].aclk = 0;
7364 combo_caches::drawing.refresh(cmbid2);
7365 }
7366 344 togglegrid[pos] |= (1<<lyr2); //Mark this pos toggled for this layer
7367 344 }
7368
1/3
✗ Branch 0 not taken.
✓ Branch 1 taken 2314 times.
✗ Branch 2 not taken.
2314 }
7369 446 }
7370 304304 });
7371
7372
3/4
✓ Branch 0 taken 519 times.
✓ Branch 1 taken 218 times.
✓ Branch 2 taken 519 times.
✗ Branch 3 not taken.
737 if(get_qr(qr_SWITCHES_AFFECT_MOVINGBLOCKS) && mblock2.clk)
7373 {
7374 newcombo const& cmb = combobuf[mblock2.bcombo];
7375 if(!(cmb.usrflags & cflag11) && (cmb.type == cCSWITCH || cmb.type == cCSWITCHBLOCK) && cmb.attribytes[0] < 32)
7376 {
7377 if(flags&(1<<cmb.attribytes[0]))
7378 {
7379 //Increment the combo/cset by the attributes
7380 int32_t cmbofs = (cmb.attributes[0]/10000L);
7381 int32_t csofs = (cmb.attributes[1]/10000L);
7382 mblock2.bcombo = BOUND_COMBO(mblock2.bcombo + cmbofs);
7383 mblock2.cs = (mblock2.cs + csofs) & 15;
7384 int32_t cmbid = mblock2.bcombo;
7385 if(combobuf[cmbid].animflags & AF_CYCLE)
7386 {
7387 combobuf[cmbid].tile = combobuf[cmbid].o_tile;
7388 combobuf[cmbid].cur_frame=0;
7389 combobuf[cmbid].aclk = 0;
7390 combo_caches::drawing.refresh(cmbid);
7391 }
7392 }
7393 }
7394 }
7395
7396
2/2
✓ Branch 0 taken 224 times.
✓ Branch 1 taken 513 times.
737 if (is_active_screen)
7397 {
7398 513 int screen_index_offset = get_region_screen_offset(m->screen);
7399 513 word c = m->numFFC();
7400
2/2
✓ Branch 0 taken 334 times.
✓ Branch 1 taken 513 times.
847 for (int q = 0; q < c; ++q)
7401 {
7402 334 auto ffc_handle = *m->getFFCHandle(q, screen_index_offset);
7403
1/2
✓ Branch 0 taken 334 times.
✗ Branch 1 not taken.
363 trig_each_combo_trigger(ffc_handle, [&](combo_trigger const& trig){
7404
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 29 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
29 return trig.trigger_flags.get(TRIGFLAG_TRIGLEVELSTATE) && trig.trig_lstate < 32 && (flags&(1<<trig.trig_lstate));
7405 }, ctrigSWITCHSTATE);
7406 334 }
7407 513 }
7408 54044 }
7409
7410 1 void toggle_gswitches(int32_t state, bool entry)
7411 {
7412 2 for_every_base_screen_in_region([&](mapscr* scr, unsigned int region_scr_x, unsigned int region_scr_y) {
7413 1 toggle_gswitches(state, entry, create_screen_handles(scr));
7414 1 });
7415 1 }
7416 1 void toggle_gswitches(int32_t state, bool entry, const screen_handles_t& screen_handles)
7417 {
7418 1 bool states[256] = {false};
7419 1 states[state] = true;
7420 1 toggle_gswitches(states, entry, screen_handles);
7421 1 }
7422 15216334 void toggle_gswitches(bool* states, bool entry, const screen_handles_t& screen_handles)
7423 {
7424
1/2
✓ Branch 0 taken 15216334 times.
✗ Branch 1 not taken.
15216334 if(!states) return;
7425
7426 15216334 auto& combo_cache = combo_caches::gswitch;
7427 15216334 mapscr* base_scr = screen_handles[0].base_scr;
7428 15216334 int screen = base_scr->screen;
7429 15216334 bool is_active_screen = is_in_current_region(base_scr);
7430 15216334 byte togglegrid[176] = {0};
7431
2/2
✓ Branch 0 taken 15216334 times.
✓ Branch 1 taken 106514338 times.
121730672 for(int32_t lyr = 0; lyr <= 6; ++lyr)
7432 {
7433 106514338 mapscr* scr = screen_handles[lyr].scr;
7434
2/2
✓ Branch 0 taken 32314143 times.
✓ Branch 1 taken 74200195 times.
106514338 if (!scr)
7435 74200195 continue;
7436
7437
2/2
✓ Branch 0 taken 32314143 times.
✓ Branch 1 taken 5687289168 times.
5719603311 for(int32_t pos = 0; pos < 176; ++pos)
7438 {
7439 5687289168 int cid = scr->data[pos];
7440 5687289168 auto& mini_cmb = combo_cache.minis[cid];
7441
7442
2/2
✓ Branch 0 taken 93475360 times.
✓ Branch 1 taken 5593813808 times.
5687289168 if (is_active_screen)
7443 {
7444
2/2
✓ Branch 0 taken 5593811926 times.
✓ Branch 1 taken 1882 times.
5593813808 if (mini_cmb.trigger_global_state)
7445 {
7446 1882 auto rpos_handle = get_rpos_handle_for_screen(screen, lyr, pos);
7447
1/2
✓ Branch 0 taken 1882 times.
✗ Branch 1 not taken.
3764 trig_each_combo_trigger(rpos_handle, [&](combo_trigger const& trig){
7448
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1882 times.
1882 return trig.trigger_flags.get(TRIGFLAG_TRIGGLOBALSTATE) && states[trig.trig_gstate];
7449 }, ctrigSWITCHSTATE);
7450 1882 }
7451 5593813808 }
7452
7453
2/2
✓ Branch 0 taken 40395 times.
✓ Branch 1 taken 5687248773 times.
5687289168 if (!mini_cmb.has_global_state)
7454 5687248773 continue;
7455
7456 40395 newcombo const& cmb = combobuf[cid];
7457
2/4
✓ Branch 0 taken 40395 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 40395 times.
40395 if(cmb.type == cCSWITCH || cmb.type == cCSWITCHBLOCK)
7458 {
7459 if(states[cmb.attribytes[0]])
7460 {
7461 set<int32_t> oldData;
7462 //Increment the combo/cset by the attributes
7463 int32_t cmbofs = (cmb.attributes[0]/10000L);
7464 int32_t csofs = (cmb.attributes[1]/10000L);
7465 oldData.insert(scr->data[pos]);
7466 scr->data[pos] = BOUND_COMBO(scr->data[pos] + cmbofs);
7467 scr->cset[pos] = (scr->cset[pos] + csofs) & 15;
7468 if(entry && (cmb.usrflags&cflag8))
7469 {
7470 newcombo const* tmp = &combobuf[scr->data[pos]];
7471 while(tmp->can_cycle())
7472 {
7473 bool cycle_under = (tmp->animflags & AF_CYCLEUNDERCOMBO);
7474 auto cid = cycle_under ? scr->undercombo : tmp->nextcombo;
7475 if(oldData.find(cid) != oldData.end())
7476 break;
7477 scr->data[pos] = cid;
7478 if(!(tmp->animflags & AF_CYCLENOCSET))
7479 scr->cset[pos] = cycle_under ? scr->undercset : tmp->nextcset;
7480 oldData.insert(cid);
7481 tmp = &combobuf[cid];
7482 }
7483 }
7484 int32_t cmbid = scr->data[pos];
7485 if(combobuf[cmbid].animflags & AF_CYCLE)
7486 {
7487 combobuf[cmbid].tile = combobuf[cmbid].o_tile;
7488 combobuf[cmbid].cur_frame=0;
7489 combobuf[cmbid].aclk = 0;
7490 combo_caches::drawing.refresh(cmbid);
7491 }
7492 togglegrid[pos] |= (1<<lyr); //Mark this pos toggled for this layer
7493 if(cmb.type == cCSWITCH) continue; //Switches don't toggle other layers
7494 for(int32_t lyr2 = 0; lyr2 <= 6; ++lyr2) //Toggle same pos on other layers, if flag set
7495 {
7496 if(lyr==lyr2) continue;
7497 if(!(cmb.usrflags&(1<<lyr2))) continue;
7498 if(togglegrid[pos]&(1<<lyr2)) continue;
7499 mapscr* scr_2 = lyr2 == 0 ? base_scr : get_scr_layer_valid(screen, lyr2);
7500 if(!scr_2 || !scr_2->data[pos]) //Don't increment empty space
7501 continue;
7502 newcombo const& cmb_2 = combobuf[scr_2->data[pos]];
7503 if(lyr2 > lyr && (cmb_2.type == cCSWITCH || cmb_2.type == cCSWITCHBLOCK)
7504 && (cmb_2.usrflags & cflag11) && (states[cmb_2.attribytes[0]]))
7505 continue; //This is a switch/block that will be hit later in the loop!
7506 set<int32_t> oldData2;
7507 //Increment the combo/cset by the original cmb's attributes
7508 oldData2.insert(scr_2->data[pos]);
7509 scr_2->data[pos] = BOUND_COMBO(scr_2->data[pos] + cmbofs);
7510 scr_2->cset[pos] = (scr_2->cset[pos] + csofs) & 15;
7511 if(entry && (cmb.usrflags&cflag8)) //Skip cycling on screen entry
7512 {
7513 newcombo const* tmp = &combobuf[scr_2->data[pos]];
7514 while(tmp->can_cycle())
7515 {
7516 bool cycle_under = (tmp->animflags & AF_CYCLEUNDERCOMBO);
7517 auto cid = cycle_under ? scr_2->undercombo : tmp->nextcombo;
7518 if(oldData2.find(cid) != oldData2.end())
7519 break;
7520 scr_2->data[pos] = cid;
7521 if(!(tmp->animflags & AF_CYCLENOCSET))
7522 scr_2->cset[pos] = cycle_under ? scr_2->undercset : tmp->nextcset;
7523 oldData2.insert(cid);
7524 tmp = &combobuf[cid];
7525 }
7526 }
7527 int32_t cmbid2 = scr_2->data[pos];
7528 if(combobuf[cmbid2].animflags & AF_CYCLE)
7529 {
7530 combobuf[cmbid2].tile = combobuf[cmbid2].o_tile;
7531 combobuf[cmbid2].cur_frame=0;
7532 combobuf[cmbid2].aclk = 0;
7533 combo_caches::drawing.refresh(cmbid2);
7534 }
7535 togglegrid[pos] |= (1<<lyr2); //Mark this pos toggled for this layer
7536 }
7537 }
7538 }
7539 40395 }
7540 32314143 }
7541
7542
4/4
✓ Branch 0 taken 547048 times.
✓ Branch 1 taken 14669286 times.
✓ Branch 2 taken 542304 times.
✓ Branch 3 taken 4744 times.
15216334 if(get_qr(qr_SWITCHES_AFFECT_MOVINGBLOCKS) && mblock2.clk)
7543 {
7544 4744 newcombo const& cmb = combobuf[mblock2.bcombo];
7545
2/4
✓ Branch 0 taken 4744 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4744 times.
✗ Branch 3 not taken.
4744 if((cmb.type == cCSWITCH || cmb.type == cCSWITCHBLOCK) && (cmb.usrflags & cflag11))
7546 {
7547 if(states[cmb.attribytes[0]])
7548 {
7549 //Increment the combo/cset by the attributes
7550 int32_t cmbofs = (cmb.attributes[0]/10000L);
7551 int32_t csofs = (cmb.attributes[1]/10000L);
7552 mblock2.bcombo = BOUND_COMBO(mblock2.bcombo + cmbofs);
7553 mblock2.cs = (mblock2.cs + csofs) & 15;
7554 int32_t cmbid = mblock2.bcombo;
7555 if(combobuf[cmbid].animflags & AF_CYCLE)
7556 {
7557 combobuf[cmbid].tile = combobuf[cmbid].o_tile;
7558 combobuf[cmbid].cur_frame=0;
7559 combobuf[cmbid].aclk = 0;
7560 combo_caches::drawing.refresh(cmbid);
7561 }
7562 }
7563 }
7564 4744 }
7565
7566
2/2
✓ Branch 0 taken 413479 times.
✓ Branch 1 taken 14802855 times.
15216334 if(is_active_screen)
7567 {
7568 14802855 int screen_index_offset = get_region_screen_offset(screen);
7569 14802855 word c = base_scr->numFFC();
7570
2/2
✓ Branch 0 taken 441793087 times.
✓ Branch 1 taken 14802855 times.
456595942 for (int q = 0; q < c; ++q)
7571 {
7572 441793087 auto ffc_handle = *base_scr->getFFCHandle(q, screen_index_offset);
7573
1/2
✓ Branch 0 taken 441793087 times.
✗ Branch 1 not taken.
442021875 trig_each_combo_trigger(ffc_handle, [&](combo_trigger const& trig){
7574
1/2
✓ Branch 0 taken 228788 times.
✗ Branch 1 not taken.
228788 return trig.trigger_flags.get(TRIGFLAG_TRIGGLOBALSTATE) && states[trig.trig_gstate];
7575 }, ctrigSWITCHSTATE);
7576 441793087 }
7577 14802855 }
7578 15216334 }
7579 53805 void toggle_gswitches_load(const screen_handles_t& screen_handles)
7580 {
7581 bool states[256];
7582
2/2
✓ Branch 0 taken 13774080 times.
✓ Branch 1 taken 53805 times.
13827885 for(auto q = 0; q < 256; ++q)
7583 {
7584 13774080 states[q] = game->gswitch_timers[q] != 0;
7585 13774080 }
7586 53805 toggle_gswitches(states, true, screen_handles);
7587 53805 }
7588 14773160 void run_gswitch_timers()
7589 {
7590 14773160 bool states[256] = {false};
7591 14773160 auto& m = game->gswitch_timers.mut_inner();
7592
2/2
✓ Branch 0 taken 3777886720 times.
✓ Branch 1 taken 14773160 times.
3792659880 for(auto it = m.begin(); it != m.end();)
7593 {
7594
2/2
✓ Branch 0 taken 3777886120 times.
✓ Branch 1 taken 600 times.
3777886720 if(it->second > 0)
7595
2/2
✓ Branch 0 taken 599 times.
✓ Branch 1 taken 1 times.
600 if(!--it->second)
7596 {
7597 1 states[it->first] = true;
7598 1 it = m.erase(it);
7599 1 continue;
7600 }
7601 3777886719 ++it;
7602 }
7603 29935688 for_every_base_screen_in_region([&](mapscr* scr, unsigned int region_scr_x, unsigned int region_scr_y) {
7604 15162528 toggle_gswitches(states, false, create_screen_handles(scr));
7605 15162528 });
7606 14773160 }
7607 1116 void onload_gswitch_timers() //Reset all timers that were counting down, no trigger necessary
7608 {
7609
2/2
✓ Branch 0 taken 285696 times.
✓ Branch 1 taken 1116 times.
286812 for(auto q = 0; q < 256; ++q)
7610 {
7611
1/2
✓ Branch 0 taken 285696 times.
✗ Branch 1 not taken.
285696 if(game->gswitch_timers[q] > 0)
7612 game->gswitch_timers[q] = 0;
7613 285696 }
7614 1116 }
7615
7616 /**** View Map ****/
7617
7618 int32_t mapres = 0;
7619 int32_t view_map_show_mode = 3;
7620
7621 124544 bool displayOnMap(int32_t x, int32_t y)
7622 {
7623 124544 int32_t s = (y<<4) + x;
7624 124544 int mi = mapind(cur_map, s);
7625
2/2
✓ Branch 0 taken 67891 times.
✓ Branch 1 taken 56653 times.
124544 if (!(game->maps[mi]&mVISITED))
7626 67891 return false;
7627
7628 // Don't display if not part of DMap
7629
4/4
✓ Branch 0 taken 15628 times.
✓ Branch 1 taken 41025 times.
✓ Branch 2 taken 4655 times.
✓ Branch 3 taken 4311 times.
65619 if(((DMaps[cur_dmap].flags&dmfDMAPMAP) &&
7630
1/2
✓ Branch 0 taken 15628 times.
✗ Branch 1 not taken.
15628 (DMaps[cur_dmap].type != dmOVERW) &&
7631
2/2
✓ Branch 0 taken 12495 times.
✓ Branch 1 taken 3133 times.
15628 !(x >= DMaps[cur_dmap].xoff &&
7632
2/2
✓ Branch 0 taken 8966 times.
✓ Branch 1 taken 3529 times.
12495 x < DMaps[cur_dmap].xoff+8 &&
7633 8966 DMaps[cur_dmap].grid[y]&(128>>(x-DMaps[cur_dmap].xoff)))))
7634 10973 return false;
7635 else
7636 45680 return true;
7637 124544 }
7638
7639 973 void ViewMap()
7640 {
7641 973 ViewingMap = true;
7642
7643 973 BITMAP* mappic = NULL;
7644 static double scales[17] =
7645 {
7646 0.03125, 0.04419, 0.0625, 0.08839, 0.125, 0.177, 0.25, 0.3535,
7647 0.50, 0.707, 1.0, 1.414, 2.0, 2.828, 4.0, 5.657, 8.0
7648 };
7649
7650 973 int32_t px = ((8-(cur_screen&15)) << 9) - 256;
7651 973 int32_t py = ((4-(cur_screen>>4)) * 352) - 176;
7652 973 int32_t lx = ((cur_screen&15)<<8) + HeroX()+8;
7653 973 int32_t ly = ((cur_screen>>4)*176) + HeroY()+8;
7654 973 int32_t sc = 6;
7655
7656 973 bool done=false, redraw=true;
7657
7658 973 mappic = create_bitmap_ex(8,(256*16)>>mapres,(176*8)>>mapres);
7659
7660
1/2
✓ Branch 0 taken 973 times.
✗ Branch 1 not taken.
973 if(!mappic)
7661 {
7662 enter_sys_pal();
7663 jwin_alert("View Map","Not enough memory.",NULL,NULL,"OK",NULL,13,27,get_zc_font(font_lfont));
7664 exit_sys_pal();
7665 return;
7666 }
7667
7668 973 clear_to_color(mappic, WHITE);
7669
7670 973 auto prev_viewport = viewport;
7671 973 viewport.x = 0;
7672 973 viewport.y = 0;
7673
7674 // draw the map
7675 973 BITMAP* screen_bmp = create_bitmap_ex(8, 256, 176);
7676 973 combotile_add_x = 256;
7677 973 combotile_add_y = 0;
7678
2/2
✓ Branch 0 taken 7784 times.
✓ Branch 1 taken 973 times.
8757 for(int32_t y=0; y<8; y++)
7679 {
7680
2/2
✓ Branch 0 taken 124544 times.
✓ Branch 1 taken 7784 times.
132328 for(int32_t x=0; x<16; x++)
7681 {
7682
2/2
✓ Branch 0 taken 45680 times.
✓ Branch 1 taken 78864 times.
124544 if (!displayOnMap(x, y))
7683 78864 continue;
7684
7685 45680 int screen = map_scr_xy_to_index(x, y);
7686 45680 auto scrs = loadscr2(screen);
7687 45680 mapscr* scr = &scrs[0];
7688
2/4
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 45680 times.
✗ Branch 3 not taken.
45680 if (!scr->is_valid())
7689 continue;
7690
7691 screen_handles_t screen_handles;
7692
2/2
✓ Branch 0 taken 45680 times.
✓ Branch 1 taken 319760 times.
365440 for (int i = 0; i <= 6; i++)
7693
3/4
✓ Branch 0 taken 319760 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 103790 times.
✓ Branch 3 taken 215970 times.
319760 screen_handles[i] = {scr, scrs[i].is_valid() ? &scrs[i] : nullptr, screen, i};
7694
7695 45680 int xx = 0;
7696 45680 int yy = -playing_field_offset;
7697
7698
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 45660 times.
45680 if(XOR(scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
7699 {
7700
1/2
✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
20 do_layer(screen_bmp, 0, screen_handles[2], xx, yy);
7701
1/2
✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
20 do_ffc_layer(screen_bmp, -2, screen_handles[0], xx, yy);
7702 20 }
7703
7704
2/2
✓ Branch 0 taken 175 times.
✓ Branch 1 taken 45505 times.
45680 if(XOR(scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
7705 {
7706
1/2
✓ Branch 0 taken 175 times.
✗ Branch 1 not taken.
175 do_layer(screen_bmp, 0, screen_handles[3], xx, yy);
7707
1/2
✓ Branch 0 taken 175 times.
✗ Branch 1 not taken.
175 do_ffc_layer(screen_bmp, -3, screen_handles[0], xx, yy);
7708 175 }
7709
7710
2/4
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 45680 times.
✗ Branch 3 not taken.
45680 if(lenscheck(scr,0)) putscr(scr, screen_bmp, 0, 0);
7711
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 do_ffc_layer(screen_bmp, 0, screen_handles[0], xx, yy);
7712
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 do_layer(screen_bmp, 0, screen_handles[1], xx, yy);
7713
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 do_ffc_layer(screen_bmp, 1, screen_handles[0], xx, yy);
7714
7715
2/2
✓ Branch 0 taken 45660 times.
✓ Branch 1 taken 20 times.
45680 if(!XOR((scr->flags7&fLAYER2BG), DMaps[cur_dmap].flags&dmfLAYER2BG))
7716 {
7717
1/2
✓ Branch 0 taken 45660 times.
✗ Branch 1 not taken.
45660 do_layer(screen_bmp, 0, screen_handles[2], xx, yy);
7718
1/2
✓ Branch 0 taken 45660 times.
✗ Branch 1 not taken.
45660 do_ffc_layer(screen_bmp, 2, screen_handles[0], xx, yy);
7719 45660 }
7720
7721
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 putscrdoors(scr, screen_bmp, xx, yy);
7722
2/2
✓ Branch 0 taken 41678 times.
✓ Branch 1 taken 4002 times.
45680 if (get_qr(qr_PUSHBLOCK_SPRITE_LAYER))
7723 {
7724
1/2
✓ Branch 0 taken 41678 times.
✗ Branch 1 not taken.
41678 do_layer(screen_bmp, -2, screen_handles[0], xx, yy);
7725
2/2
✓ Branch 0 taken 1782 times.
✓ Branch 1 taken 39896 times.
41678 if(get_qr(qr_PUSHBLOCK_LAYER_1_2))
7726 {
7727
1/2
✓ Branch 0 taken 1782 times.
✗ Branch 1 not taken.
1782 do_layer(screen_bmp,-2, screen_handles[1], xx, yy);
7728
1/2
✓ Branch 0 taken 1782 times.
✗ Branch 1 not taken.
1782 do_layer(screen_bmp,-2, screen_handles[2], xx, yy);
7729 1782 }
7730 41678 }
7731
7732
2/2
✓ Branch 0 taken 45505 times.
✓ Branch 1 taken 175 times.
45680 if(!XOR((scr->flags7&fLAYER3BG), DMaps[cur_dmap].flags&dmfLAYER3BG))
7733 {
7734
1/2
✓ Branch 0 taken 45505 times.
✗ Branch 1 not taken.
45505 do_layer(screen_bmp, 0, screen_handles[3], xx, yy);
7735
1/2
✓ Branch 0 taken 45505 times.
✗ Branch 1 not taken.
45505 do_ffc_layer(screen_bmp, 3, screen_handles[0], xx, yy);
7736 45505 }
7737
7738
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 do_layer(screen_bmp, 0, screen_handles[4], xx, yy);
7739
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 do_ffc_layer(screen_bmp, 4, screen_handles[0], xx, yy);
7740
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 do_layer(screen_bmp, -1, screen_handles[0], xx, yy);
7741
2/2
✓ Branch 0 taken 5784 times.
✓ Branch 1 taken 39896 times.
45680 if(get_qr(qr_OVERHEAD_COMBOS_L1_L2))
7742 {
7743
1/2
✓ Branch 0 taken 5784 times.
✗ Branch 1 not taken.
5784 do_layer(screen_bmp,-1, screen_handles[1], xx, yy);
7744
1/2
✓ Branch 0 taken 5784 times.
✗ Branch 1 not taken.
5784 do_layer(screen_bmp,-1, screen_handles[2], xx, yy);
7745 5784 }
7746
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 do_layer(screen_bmp, 0, screen_handles[5], xx, yy);
7747
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 do_ffc_layer(screen_bmp, 5, screen_handles[0], xx, yy);
7748
2/4
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 45680 times.
45680 if(replay_version_check(40))
7749 do_ffc_layer(screen_bmp, -1, screen_handles[0], xx, yy);
7750
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 do_layer(screen_bmp, 0, screen_handles[6], xx, yy);
7751
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 do_ffc_layer(screen_bmp, 6, screen_handles[0], xx, yy);
7752
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 do_ffc_layer(screen_bmp, 7, screen_handles[0], xx, yy);
7753
7754
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 stretch_blit(screen_bmp, mappic, 0, 0, 256, 176, x<<(8-mapres), (y*176)>>mapres, 256>>mapres, 176>>mapres);
7755
1/3
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 45680 times.
45680 }
7756 7784 }
7757
7758 973 viewport = prev_viewport;
7759 973 combotile_add_x = 0;
7760 973 combotile_add_y = 0;
7761
7762 973 destroy_bitmap(screen_bmp);
7763 973 clear_keybuf();
7764 973 pause_all_sfx();
7765
7766 // view it
7767 973 int32_t delay = 0;
7768
7769 973 do
7770 {
7771
2/2
✓ Branch 0 taken 178717 times.
✓ Branch 1 taken 29891 times.
208608 if (replay_version_check(0, 11))
7772 29891 load_control_state();
7773
7774 208608 int32_t step = int32_t(16.0/scales[sc]);
7775 208608 step = (step>>1) + (step&1);
7776 208608 bool r = cRbtn();
7777
7778
1/2
✓ Branch 0 taken 208608 times.
✗ Branch 1 not taken.
208608 if(cLbtn())
7779 {
7780 step <<= 2;
7781 delay = 0;
7782 }
7783
7784
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 208608 times.
208608 if(r)
7785 {
7786 if(rUp())
7787 {
7788 py+=step;
7789 redraw=true;
7790 }
7791
7792 if(rDown())
7793 {
7794 py-=step;
7795 redraw=true;
7796 }
7797
7798 if(rLeft())
7799 {
7800 px+=step;
7801 redraw=true;
7802 }
7803
7804 if(rRight())
7805 {
7806 px-=step;
7807 redraw=true;
7808 }
7809 }
7810 else
7811 {
7812
2/2
✓ Branch 0 taken 193729 times.
✓ Branch 1 taken 14879 times.
208608 if(Up())
7813 {
7814 14879 py+=step;
7815 14879 redraw=true;
7816 14879 }
7817
7818
2/2
✓ Branch 0 taken 193574 times.
✓ Branch 1 taken 15034 times.
208608 if(Down())
7819 {
7820 15034 py-=step;
7821 15034 redraw=true;
7822 15034 }
7823
7824
2/2
✓ Branch 0 taken 182159 times.
✓ Branch 1 taken 26449 times.
208608 if(Left())
7825 {
7826 26449 px+=step;
7827 26449 redraw=true;
7828 26449 }
7829
7830
2/2
✓ Branch 0 taken 182774 times.
✓ Branch 1 taken 25834 times.
208608 if(Right())
7831 {
7832 25834 px-=step;
7833 25834 redraw=true;
7834 25834 }
7835 }
7836
7837
2/2
✓ Branch 0 taken 187444 times.
✓ Branch 1 taken 21164 times.
208608 if(delay)
7838 21164 --delay;
7839 else
7840 {
7841 187444 bool a = cAbtn();
7842 187444 bool b = cBbtn();
7843
7844
3/4
✓ Branch 0 taken 1721 times.
✓ Branch 1 taken 185723 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1721 times.
187444 if(a && !b)
7845 {
7846
1/2
✓ Branch 0 taken 1721 times.
✗ Branch 1 not taken.
1721 sc=zc_min(sc+1,16);
7847 1721 delay=8;
7848 1721 redraw=true;
7849 1721 }
7850
7851
3/4
✓ Branch 0 taken 927 times.
✓ Branch 1 taken 186517 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 927 times.
187444 if(b && !a)
7852 {
7853
2/2
✓ Branch 0 taken 926 times.
✓ Branch 1 taken 1 times.
927 sc=zc_max(sc-1,0);
7854 927 delay=8;
7855 927 redraw=true;
7856 927 }
7857 }
7858
7859
2/2
✓ Branch 0 taken 208597 times.
✓ Branch 1 taken 11 times.
208608 if(rPbtn())
7860 11 --view_map_show_mode;
7861
7862 208608 px = vbound(px,-4096,4096);
7863 208608 py = vbound(py,-1408,1408);
7864
7865 208608 double scale = scales[sc];
7866
7867
2/2
✓ Branch 0 taken 72838 times.
✓ Branch 1 taken 135770 times.
208608 if(!redraw)
7868 {
7869 135770 blit(scrollbuf_old,framebuf,256,0,0,0,256,232);
7870 135770 }
7871 else
7872 {
7873 72838 clear_to_color(framebuf,BLACK);
7874 145676 stretch_blit(mappic,framebuf,0,0,mappic->w,mappic->h,
7875 72838 int32_t(256+(int64_t(px)-mappic->w)*scale)/2,int32_t(224+(int64_t(py)-mappic->h)*scale)/2,
7876 72838 int32_t(mappic->w*scale),int32_t(mappic->h*scale));
7877
7878 72838 blit(framebuf,scrollbuf_old,0,0,256,0,256,232);
7879 72838 redraw=false;
7880 }
7881
7882 208608 int32_t x = int32_t(256+(px-((2048-int64_t(lx))*2))*scale)/2;
7883 208608 int32_t y = int32_t(224+(py-((704-int64_t(ly))*2))*scale)/2;
7884
7885
2/2
✓ Branch 0 taken 7466 times.
✓ Branch 1 taken 201142 times.
208608 if(view_map_show_mode&1)
7886 {
7887 201142 line(framebuf,x-7,y-7,x+7,y+7,(frame&3)+252);
7888 201142 line(framebuf,x+7,y-7,x-7,y+7,(frame&3)+252);
7889 201142 }
7890
7891
3/4
✓ Branch 0 taken 5600 times.
✓ Branch 1 taken 203008 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 5600 times.
208608 if(view_map_show_mode&2 || r)
7892 203008 textprintf_ex(framebuf,font,224,216,WHITE,BLACK,"%1.2f",scale);
7893
7894
1/2
✓ Branch 0 taken 208608 times.
✗ Branch 1 not taken.
208608 if(r)
7895 {
7896 textprintf_ex(framebuf,font,0,208,WHITE,BLACK,"m: %d %d",px,py);
7897 textprintf_ex(framebuf,font,0,216,WHITE,BLACK,"x: %d %d",x,y);
7898 }
7899
7900 208608 advanceframe(false, false);
7901
2/2
✓ Branch 0 taken 29891 times.
✓ Branch 1 taken 178717 times.
208608 if (replay_version_check(11))
7902 178717 load_control_state();
7903
7904
2/2
✓ Branch 0 taken 207636 times.
✓ Branch 1 taken 972 times.
208608 if(getInput(btnS, true, false, true)) //rSbtn
7905 972 done = true;
7906
7907
2/2
✓ Branch 0 taken 973 times.
✓ Branch 1 taken 207635 times.
417216 }
7908
2/2
✓ Branch 0 taken 972 times.
✓ Branch 1 taken 207636 times.
208608 while(!done && !Quit);
7909
7910 973 ViewingMap = false;
7911 973 destroy_bitmap(mappic);
7912 973 resume_all_sfx();
7913 973 }
7914
7915 1075 int32_t onViewMap()
7916 {
7917
4/6
✓ Branch 0 taken 1075 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1075 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 102 times.
✓ Branch 5 taken 973 times.
1075 if(Playing && cur_screen<128 && DMaps[cur_dmap].flags&dmfVIEWMAP)
7918 {
7919 973 clear_to_color(framebuf,BLACK);
7920 973 textout_centre_ex(framebuf,font,"Drawing map...",128,108,WHITE,BLACK);
7921 973 advanceframe(true);
7922 973 ViewMap();
7923 973 }
7924
7925 1075 return D_O_K;
7926 }
7927
7928 35757403 bool isGrassType(int32_t type)
7929 {
7930
2/2
✓ Branch 0 taken 35080991 times.
✓ Branch 1 taken 676412 times.
35757403 switch(type)
7931 {
7932 case cTALLGRASS:
7933 case cTALLGRASSNEXT:
7934 case cTALLGRASSTOUCHY:
7935 676412 return true;
7936 }
7937
7938 35080991 return false;
7939 35757403 }
7940
7941 20914 bool isFlowersType(int32_t type)
7942 {
7943
2/2
✓ Branch 0 taken 16574 times.
✓ Branch 1 taken 4340 times.
20914 switch(type)
7944 {
7945 case cFLOWERS:
7946 case cFLOWERSTOUCHY:
7947 4340 return true;
7948 }
7949
7950 16574 return false;
7951 20914 }
7952
7953 bool isGenericType(int32_t type)
7954 {
7955 switch(type)
7956 {
7957 case cTRIGGERGENERIC:
7958 return true;
7959 }
7960
7961 return false;
7962 }
7963
7964 26056 bool isBushType(int32_t type)
7965 {
7966
2/2
✓ Branch 0 taken 20914 times.
✓ Branch 1 taken 5142 times.
26056 switch(type)
7967 {
7968 case cBUSH:
7969 case cBUSHNEXT:
7970 case cBUSHTOUCHY:
7971 case cBUSHNEXTTOUCHY:
7972
7973 5142 return true;
7974 }
7975
7976 20914 return false;
7977 26056 }
7978
7979 bool isSlashType(int32_t type)
7980 {
7981 switch(type)
7982 {
7983 case cSLASH:
7984 case cSLASHITEM:
7985 case cSLASHTOUCHY:
7986 case cSLASHITEMTOUCHY:
7987 case cSLASHNEXT:
7988 case cSLASHNEXTITEM:
7989 case cSLASHNEXTTOUCHY:
7990 case cSLASHNEXTITEMTOUCHY:
7991 return true;
7992 }
7993
7994 return false;
7995 }
7996
7997 15695 bool isCuttableNextType(int32_t type)
7998 {
7999
2/2
✓ Branch 0 taken 9788 times.
✓ Branch 1 taken 5907 times.
15695 switch(type)
8000 {
8001 case cSLASHNEXT:
8002 case cSLASHNEXTITEM:
8003 case cTALLGRASSNEXT:
8004 case cBUSHNEXT:
8005 case cSLASHNEXTTOUCHY:
8006 case cSLASHNEXTITEMTOUCHY:
8007 case cBUSHNEXTTOUCHY:
8008 5907 return true;
8009 }
8010
8011 9788 return false;
8012 15695 }
8013
8014 17546 bool isTouchyType(int32_t type)
8015 {
8016
2/2
✓ Branch 0 taken 6050 times.
✓ Branch 1 taken 11496 times.
17546 switch(type)
8017 {
8018 case cSLASHTOUCHY:
8019 case cSLASHITEMTOUCHY:
8020 case cBUSHTOUCHY:
8021 case cFLOWERSTOUCHY:
8022 case cTALLGRASSTOUCHY:
8023 case cSLASHNEXTTOUCHY:
8024 case cSLASHNEXTITEMTOUCHY:
8025 case cBUSHNEXTTOUCHY:
8026 11496 return true;
8027 }
8028
8029 6050 return false;
8030 17546 }
8031
8032 29332374 bool isCuttableType(int32_t type)
8033 {
8034
2/2
✓ Branch 0 taken 28883109 times.
✓ Branch 1 taken 449265 times.
29332374 switch(type)
8035 {
8036 case cSLASH:
8037 case cSLASHITEM:
8038 case cBUSH:
8039 case cFLOWERS:
8040 case cTALLGRASS:
8041 case cTALLGRASSNEXT:
8042 case cSLASHNEXT:
8043 case cSLASHNEXTITEM:
8044 case cBUSHNEXT:
8045
8046 case cSLASHTOUCHY:
8047 case cSLASHITEMTOUCHY:
8048 case cBUSHTOUCHY:
8049 case cFLOWERSTOUCHY:
8050 case cTALLGRASSTOUCHY:
8051 case cSLASHNEXTTOUCHY:
8052 case cSLASHNEXTITEMTOUCHY:
8053 case cBUSHNEXTTOUCHY:
8054 449265 return true;
8055 }
8056
8057 28883109 return false;
8058 29332374 }
8059
8060 17322 bool isCuttableItemType(int32_t type)
8061 {
8062
2/2
✓ Branch 0 taken 424 times.
✓ Branch 1 taken 16898 times.
17322 switch(type)
8063 {
8064 case cSLASHITEM:
8065 case cBUSH:
8066 case cFLOWERS:
8067 case cTALLGRASS:
8068 case cTALLGRASSNEXT:
8069 case cSLASHNEXTITEM:
8070 case cBUSHNEXT:
8071
8072 case cSLASHITEMTOUCHY:
8073 case cBUSHTOUCHY:
8074 case cFLOWERSTOUCHY:
8075 case cTALLGRASSTOUCHY:
8076 case cSLASHNEXTITEMTOUCHY:
8077 case cBUSHNEXTTOUCHY:
8078 16898 return true;
8079 }
8080
8081 424 return false;
8082 17322 }
8083
8084 66 bool is_push(mapscr* m, int32_t pos)
8085 {
8086
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 66 times.
66 if(is_push_flag(m->sflag[pos]))
8087 return true;
8088 66 newcombo const& cmb = combobuf[m->data[pos]];
8089
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 66 times.
66 if(is_push_flag(cmb.flag))
8090 return true;
8091
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 52 times.
66 if(cmb.type == cPUSHBLOCK)
8092 14 return true;
8093
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 52 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
52 if(cmb.type == cSWITCHHOOK && (cmb.usrflags&cflag7))
8094 return true; //Counts as 'pushblock' flag
8095 52 return false;
8096 66 }
8097
8098 412 static std::map<int, screen_state_t> screen_states;
8099
8100 35854 std::map<int, screen_state_t>& get_screen_states()
8101 {
8102 35854 return screen_states;
8103 }
8104
8105 44182923 screen_state_t& get_screen_state(int screen)
8106 {
8107 44182923 return screen_states[screen];
8108 }
8109
8110 575 void clear_screen_states()
8111 {
8112 575 screen_states.clear();
8113 575 }
8114
8115 1439 void screen_item_set_state(int screen, ScreenItemState state)
8116 {
8117 1439 get_screen_state(screen).item_state = state;
8118 1439 }
8119
8120 37019 void mark_visited(int screen)
8121 {
8122
2/2
✓ Branch 0 taken 475 times.
✓ Branch 1 taken 36544 times.
37019 if (screen < 0x80)
8123 {
8124
2/2
✓ Branch 0 taken 24611 times.
✓ Branch 1 taken 11933 times.
36544 if(DMaps[cur_dmap].flags&dmfVIEWMAP)
8125 11933 game->maps[mapind(cur_map, screen)] |= mVISITED;
8126
8127 36544 markBmap(-1, screen);
8128 36544 }
8129 37019 }
8130